源码来自jdk1.8
TreeMap, TreeSet, PriorityQueue等天生有序的数据结构,或是Arrays, Collections方法类的排序函数等中,需要对集合元素进行比较,如果不是String或是基本类型等平台自带的类型,就需要自己实现比较元素的方法。
对于Collections来说:
public static > void sort(List list) {
list.sort(null);
}
要么是list中的类型原本就实现了Comparable接口
public static void sort(List list, Comparator super T> c) {
list.sort(c);
}
要么是在调用sort的时候提供了这个类型的比较器(实现Comparator接口)
对于Arrays来说:
与Collections也是一样的,提供一个Comparator或者实现Comparable
public static void sort(T[] a, Comparator super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
/**
* Sorts the specified array of objects into ascending order, according
* to the {@linkplain Comparable natural ordering} of its elements.
* All elements in the array must implement the {@link Comparable}
* interface. Furthermore, all elements in the array must be
* mutually comparable (that is, {@code e1.compareTo(e2)} must
* not throw a {@code ClassCastException} for any elements {@code e1}
* and {@code e2} in the array).
*
* @param a the array to be sorted
* @throws ClassCastException if the array contains elements that are not
* mutually comparable (for example, strings and integers)
* @throws IllegalArgumentException (optional) if the natural
* ordering of the array elements is found to violate the
* {@link Comparable} contract
*/
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
}
对TreeSet,TreeMap,PriorityQueue来说:
如果元素类型没有实现Comparable接口,那么在使用的过程中,如add一个元素就会抛出如下异常:
Exception in thread "main" java.lang.ClassCastException: Collection.User cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
同样的,也可以在创建TreeMap等数据类型的时候传入一个元素类型的Comparator
由于需要进行比较,所以这些数据结构不允许null值。
什么是Mutually Comparable
为了A类和B类能够互相比较,必须满足如下要求:
- 对A类的一个对象调用compareTo时传入一个B类的对象(包括子类对象)必须是允许的,也就是不会抛出
ClassCastException
- 对B类的一个对象调用compareTo时传入一个A类的对象(包括子类对象)必须是允许的,也就是不会抛出
ClassCastException
- 如果a.compareTo(b)返回x,那么b.compareTo(a)必须返回一个相反符号的y,如果x==0,那么y==0
Comparable
public interface Comparable {
/**
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
*/
public int compareTo(T o);
}
Comparator
Comparator
public interface Comparator {
/**
* Compares its two arguments for order. Returns a negative integer,
* zero, or a positive integer as the first argument is less than, equal
* to, or greater than the second.
*
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
* @throws NullPointerException if an argument is null and this
* comparator does not permit null arguments
* @throws ClassCastException if the arguments' types prevent them from
* being compared by this comparator.
*/
int compare(T o1, T o2);
// 省略了其他方法
}
Comparator vs Comparable
java.lang.Comparable
用来确定一个类的对象的自然顺序(natural ordering), 然而你可以根据自己的需要使用java.util.Comparator
来确定任何的对象顺序。
你只能通过Comparable确定一个固定的对象顺序,使用Comparator却可以实现任意多个自定义顺序。
Readmore: http://java67.blogspot.com/2013/08/difference-between-comparator-and-comparable-in-java-interface-sorting.html#ixzz490WANROH