Java中集合类的排序 Comparator与Comparable
阅读原文时间:2021年04月20日阅读:1

Comparator与Comparable的功能都是对一个集合类进行排序,但是Comparable是内部排序接口,Comparator是外部排序接口。简单的说,Comparable是利用的继承的特性,Comparator是利用了委托的特性,从单一责任原则的角度出发,建议选择用Comparator进行排序,而且在更改的时候还能直接对排序器进行修改,增强了可扩展性。

1.Comparable

我们建立一个Person类,然后需要按年龄对每一个Person对象进行排序。利用Comparable接口的话就要对Person类自身增加排序功能。
首先给出Person类

public class Person implements Comparable<Person>{
 private Integer age;

 public Person(Integer age) {
  this.age = age;
 }

 public Integer age() {
  return age;
 }

 @Override public int compareTo(Person p) {
  return this.age.compareTo(p.age);
 }
}

在Person类中只需要重写compareTo方法即可。这个Person类其实借用了Integer类的排序方法(在Integer类中已经Java已经完成了Comparable接口)。但是有一个缺点,就是Comparable方法只能依靠已经完成的类进行排序,不能自己定义。

public class Comparable1 {

 public static void main(String[] strs) {
  List<Person> list = new ArrayList<Person>();
  list.add(new Person(1));
  list.add(new Person(5));
  list.add(new Person(2));
  list.add(new Person(10));
  Collections.sort(list);
  for(Person p : list) {
   System.out.print(p.age() + " ");
  }
 }
}

得到结果

2.Comparator

这个排序方式需要新建一个能以委托方式提供排序功能的类。完成Comparator接口,并且重写其中的compare方法。
该类如下

public class Comparator1 implements Comparator<Person>{
 @Override public int compare(Person p1, Person p2) {
  return p1.age()-p2.age();
 }

利用这个类,让指定的list通过委托方式对其进行排序,具体如下:

public class Comparator_main {
 public static void main(String[] strs) {
  List<Person> list = new ArrayList<Person>();
  list.add(new Person(2));
  list.add(new Person(1));
  list.add(new Person(4));
  Collections.sort(list, new Comparator1());
  for(Person p : list) {
   System.out.print(p.age() + " ");
  }
 }
}

在这里调用了Collections.sort(对象,comparator)的方法,利用委托的方式对list中的元素进行排序。
结果如下

总结,Comparable是通过继承方式,让排序类自己具有排序功能。Comparator是建立一个提供排序的类,让待排序元素委托排序类让其对自身进行排序。为了以后的可维护性,个人认为还是Comparator能更好地运行。