Comparable和Comparator的区别
# Comparable和Comparator区别
# Comparable
自然排序:comparable接口出自java.lang
包,它有一个compareTo(Object obj)
方法用来排序。
像String,包装类等实现了Comparable接口,重写了compareTo()
方法。对于自定义类,如果需要排序的话,可以让自定义类实现Comparable接口,在compareTo()
方法中指明如何排序。
重写compareTo(obj)
规则:
如果当前对象this > 形参对象obj,返回正整数。
如果当前对象this < 形参对象obj,返回负整数。
如果当前对象this = 形参对象obj,返回零。
我们来看看String的源码:
// 实现了 Comparable 接口,说明String对象可以进行排序
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
...
// 实现了compareTo方法,通过这个方法比较两个字符串的大小
// 具体的比较方式就是比较每个字符的ASCCII,细节就不展开了。
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
我们对一组字符串进行排序:
String[] arr = new String[]{"AA", "ZZ", "DD", "XX", "CC"};
Arrays.sort(arr);
for (String s : arr) {
System.out.println(s);
}
2
3
4
5
输出的顺序为:AA、CC、DD、XX、ZZ
如果我们想要对字符串进行倒序排列该怎么办呢?或者对没有实现Comparable接口的类进行排序该怎么办?那就要使用定制排序Comparator。
# Comparator
定制排序:comparator接口出自 java.util
包,它有一个compare(Object obj1, Object obj2)
方法用来排序。
当元素的类型没有实现Comparable接口又不方便修改时,或者实现了Compareble接口的排序规则不适合当前的操作,那么可以使用Comparator对象来排序。重写compare(Object o1, Object o2)
。可以将Comparator传递给sort方法(如Collections.sort()
和Arrays.sort()
)。
先对上面的字符串数组进行倒序排列:
String[] arr = new String[]{"AA", "ZZ", "DD", "XX", "CC"};
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return -o1.compareTo(o2);
}
});
for (String s : arr) {
System.out.println(s);
}
2
3
4
5
6
7
8
9
10
输出的顺序为:ZZ、XX、DD、CC、AA
上面的代码可以通过lambda表达式和函数式编程进行简化:
String[] arr = new String[]{"AA", "ZZ", "DD", "XX", "CC"};
Arrays.sort(arr, (o1, o2) -> -o1.compareTo(o2));
Arrays.stream(arr).forEach(System.out::println);
2
3
可以看看稍微复杂一点的案例,有下面一个二维数组,需要按从大到小的顺序排列,第0位大的数组排在前面,第0位相同时,第1位大的数排在前面。
int[][] arr = new int[][]{{2, 4}, {4, 3}, {2, 7}, {0, 1}, {2,5}, {1, 3}};
Arrays.sort(arr, (o1, o2) -> {
if (o1[0] == o2[0]) {
return o2[1] - o1[1];
} else {
return o2[0] - o1[0];
}
});
for (int[] a : arr) {
System.out.println(a[0] + ", " + a[1]);
}
2
3
4
5
6
7
8
9
10
11
# 总结
- Comparable 形容词,表示这个类具有比较的能力,Comparator 名词,比较器
- Comparable 相当于内部比较器,Comparator 相当于外部比较器
- 使用Comparable需要修改源码;使用Comparator不需要修改源码,而需要另外实现比较方法