先从表面上来看
- 功能上都是用来排序
- Comparator是在
java.util
包下,Comparable是在java.lang
包下。 - Comparable和Comparator都是接口,Comparable下只有一个int compareTo(Object o1)方法,Comparator下有多个方法,比如int compare(Object o1, Object o2)
- compareTo和compare这两个方法都是返回int(1,0,-1三个值)
实现了排序功能的集合
-
java.util.Collection.sort(List)
和java.util.Arrays.sort(Object[])
以自然顺序(natural order)来实现集合和数组的排序。【注:这里面的对象必须实现Comparable接口】 -
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);
网友评论