Java中为我们提供了两种比较机制Comparable和Comparator,他们之间有什么区别和联系呢,我们一起来探讨一下。
Comparable接口
T代表了被比较对象的类型
Comparable是排序接口。若一个类实现了Comparable接口,就意味着“该类支持排序”。即可通过Collections.sort(或Arrays.sort)进行排序。
实现Comparable接口的类的对象可以用作有序映射(TreeMap)中的键或有序集合(TreeSet)中的元素,而不需要指定比较器。
public interface Comparable<T> { public int compareTo(T o); }假设我们通过x.compareTo(y)来比较x和y的大小。若返回“负数”则x比y小;返回“0”则x=y;返回“正数”则x大于y。
Comparator
接口 T代表了被比较对象的类型
Comparator是比较器接口,同时一个函数接口,因此可以用作lambda表达式或方法引用的赋值目标。
我们通过实现Comparator类来新建一个比较器,然后通过该比较器对类进行排序。
public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }若一个类要实现Comparator接口一定要实现compareTo(T o1, T o2)函数,但可以不实现equals(Object obj)函数(Object类已经实现了)。int compare(T o1, T o2)比较o1和o2的大小。若返回“负数”则o1比o2小;返回“0”则o1=o2;返回“正数”则o1大于o2。
实例说明
创建一个Person类,实现了Comparable接口。
public class Person implements Comparable<Person> { int age; String name; ...省略构造方法、get/set、toString、等方法 @Override public int compareTo(Person person) { return name.compareTo(person.name); } }在main函数中我们创建了list数组,并利用Collections的sort函数对list进行排序。
public static void main(String[] args) { ArrayList<Person> list = new ArrayList(); list.add(new Person(20, "ccc")); list.add(new Person(30, "AAA")); list.add(new Person(10, "bbb")); list.add(new Person(40, "ddd")); System.out.println(list); Collections.sort(list); System.out.println(list); }运行结果如下:

前面提到过Comparator是一个函数接口,因此可以用作lambda表达式或方法引用的赋值目标。
public static void main(String[] args) {
AscAgeComparator ascAgeComparator = new AscAgeComparator();
List<Person> list = new ArrayList();
list.add(new Person(20, "ccc"));
list.add(new Person(30, "AAA"));
list.add(new Person(10, "bbb"));
list.add(new Person(40, "ddd"));
System.out.println(list);
//匿名内部类
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
//Lambda表达式
Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge());
//Comparator.comparingInt
Collections.sort(list, Comparator.comparingInt(Person::getAge));
System.out.println(list);
}
运行结果如下:
