comparable和comparator是java中两个用于比较大小的接口
1、comparable位于java.lang包中,实现该接口的对象表示该对象是“可比较的”,此接口强行对实现它的每个类的对象进行整体排序。该接口定义如下:
public interface Comparable<T> {
public int compareTo(T o);
}
jdk文档:实现此接口的对象列表(和数组)可以通过
Collections.sort
(和 Arrays.sort
)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals 一致。注意,null 不是任何类的实例,即使 e.equals(null) 返回 false,e.compareTo(null) 也将抛出 NullPointerException。建议(虽然不是必需的)最好使自然排序与 equals 一致。这是因为在使用自然排序与 equals 不一致的元素(或键)时,没有显式比较器的有序集合(和有序映射表)行为表现“怪异”。尤其是,这样的有序集合(或有序映射表)违背了根据 equals 方法定义的集合(或映射表)的常规协定。
2、comparator位于java.util包中,是一个比较器,可以在类的定义之外指定比较规则,在需要排序的地方将比较器传递给排序函数即可,定义如下:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
jdk文档:强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如
Collections.sort
或 Arrays.sort
),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set
或有序映射
)的顺序,或者为那些没有自然顺序
的对象 collection 提供排序。排序规则最好也是与equals一致的。
观察Collections中的排序方法,有两种方法,一种是直接比较实现了Comparable接口的可比较的对象,一种是对排序的对象指定一个定义了比较规则的比较器。两种排序方法源码如下:
public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a. length; j++) {
i.next();
i.set((T)a[j]);
}
}
public static <T> void sort (List<T> list, Comparator<? super T> c) {
Object[] a = list.toArray();
Arrays.sort(a, (Comparator)c);
ListIterator i = list.listIterator();
for (int j=0; j<a. length; j++) {
i.next();
i.set(a[j]);
}
}