美文网首页Java 杂谈Java学习笔记
认识一下Comparator和Comparable

认识一下Comparator和Comparable

作者: 邮差在行动 | 来源:发表于2018-04-17 13:35 被阅读1次

先从表面上来看

  1. 功能上都是用来排序
  2. Comparator是在java.util包下,Comparable是在java.lang包下。
  3. Comparable和Comparator都是接口,Comparable下只有一个int compareTo(Object o1)方法,Comparator下有多个方法,比如int compare(Object o1, Object o2)
  4. compareTo和compare这两个方法都是返回int(1,0,-1三个值)

实现了排序功能的集合

  1. java.util.Collection.sort(List)java.util.Arrays.sort(Object[])自然顺序(natural order)来实现集合和数组的排序。【注:这里面的对象必须实现Comparable接口
  2. java.util.Collections.sort(List, Comparator)java.util.Arrays.sort(Object[], Comparator)可以指定Comparator来排序。

举例

基础类型排序(Sort an array/list of primitive type)

int[] ints = {11,2,44,5,12};
Arrays.sort(ints);
System.out.println(Arrays.toString(ints));

List<Integer> integers = new ArrayList<>();
integers.add(12);
integers.add(32);
integers.add(5);
integers.add(3);
integers.add(42);
Collections.sort(integers);
System.out.println(integers);

输出结果:

[2, 5, 11, 12, 44]
[3, 5, 12, 32, 42]

对String数组、集合排序

List<String> strList = new ArrayList<>();
strList.add("123");
strList.add("abc");
strList.add("eee");
strList.add("1w2");
Collections.sort(strList);
System.out.println(strList);

String[] strs =  {"1r","e2","1q","2","f2"};
Arrays.sort(strs);
System.out.println(Arrays.toString(strs));

输出结果:

[123, 1w2, abc, eee]
[1q, 1r, 2, e2, f2]

对自定义对象排序

自定义一个User类

public class User {
    private int id;
    private String name;
    private String email;
    public User(int id, String name, String email) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
    }
    public User() {
        super();
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", email=" + email + "]";
    }
    //omit the setter and getter
}

对这个对象的数组、集合排序

List<User> userList = new ArrayList<>();
userList.add(new User(10,"na","a@a.com"));
userList.add(new User(21,"bna","ba@a.com"));
userList.add(new User(15,"cna","ca@a.com"));

Collections.sort(userList);

如果排序方法是 Collections.sort(userList),就会报编译错误:
The method sort(List<T>) in the type Collections is not applicable for the arguments (List<User>)

那该怎么办呢?

有2种解决办法:
1)自己指定比较器
Collections.sort(userList, Comparator.comparing(User::getId));
2)让User实现Comparable接口

public class User implements Comparable<User>{
    //..............omit 
    
    @Override
    public int compareTo(User o) {
        return Integer.compare(this.getId(), o.getId());
    }
}

这样再使用Collections.sort(userList)就可以了。

实际应用

在实际情况中,如果我们定义的对象需要用于比较,而且要比较的字段很多时,我们可以让这个类实现Comparable接口,然后再调用不同的比较器(Comparator)。
举例:

private static final Comparator<User> IDCOMPARATOR = Comparator.comparing(User::getId);
private static final Comparator<User> IDNameCOMPARATOR = Comparator.comparing(User::getId).thenComparing(User::getName);
private static final Comparator<User> NameCOMPARATOR = Comparator.comparing(User::getName);
private static final Comparator<User> NameCOMPARATORReversed = Comparator.comparing(User::getId).reversed();
private static final Comparator<User> IDNameEmailCOMPARATOR = Comparator.comparing(User::getId).thenComparing(User::getName).thenComparing(User::getEmail);
    
@Override
public int compareTo(User o) {
    return IDNameEmailCOMPARATOR.compare(this, o);
    //return Integer.compare(this.getId(), o.getId());
}

其中compareTo方法可以指定你实际最常用的比较方式。
如果有特殊需要,可以在调用sort方法时指定你的比较器:Collections.sort(userList, NameCOMPARATOR);

相关文章

网友评论

    本文标题:认识一下Comparator和Comparable

    本文链接:https://www.haomeiwen.com/subject/udwukftx.html