最近遇到一个问题、需要对List中的对象进行排序。无脑写代码的解决方案是:取出来排序。当然这不符合我们程序员的追求。
Java中有两个接口专门用于排序、比较。它们就是comparable和comparator。也有人称之为内部比较器和外部比较器。
内部比较器 comparable:它重要用在创建类时实现,如果一个类需要用到排序,则可以实现这个接口。
外部比较器comparator:它更像是一个补救措施,是将对象按照该比较器的规则进行比较。我们可以用comparator实现多种比较方式,按姓名按学号按成绩等等。这些功能在一开始创建对象时,并没有完全考虑。
先看一下内部比较器comparable:
public interface Comparable<T> {
public int compareTo(T o);
}
一共只有一个方法,那就是compareTo(T o); 返回值为int型:
负数:当前对象小于参数、
0:当前对象等于参数
正数:当前对象大于参数
再看一下外部比较器comparator:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
...
}
主要抽象方法为compare(T o1,T o2);该方法同内部比较器一样,是一个int型
负数:o1 < o2
0: o1 = o2
正数:o1 > o2
了解了接口之后,我们先直接看一下用法。
先创建一个Student类,并实现comparable接口。用于生成student对象来进行排序、对姓名排序。
class Student implements Comparable<Student>{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int compareTo(Student student){
return name.compareTo(student.getName());
}
public String toString() {
return id + " - " +name;
}
}
我们主要看一下compareTo(Student student);方法。该方法是用于实现内部比较器。
name.compareTo(student,getName()); 就是我们的比较规则。是按照name属性来比较的。
这条语句的compareTo。调用的则是String类中的compareTo方法。String已经实现了内部比较器。大家不要看成递归调用。
写一个类,用于测试。该类拥有一个List,用于存放student对象。
public class Compare {
public static List<Student> list;
public static void main(String[] args){
list= new LinkedList<>();
list.add(new Student(1,"zhou"));
list.add(new Student(2,"tom"));
list.add(new Student(3,"kiki"));
list.add(new Student(4,"jim"));
list.add(new Student(5,"sum"));
Collections.sort(list);
System.out.println(list);
// Collections.sort(list,new IdComparetor());
// System.out.println(list);
}
}
执行结果是:
[4 - jim, 3 - kiki, 5 - sum, 2 - tom, 1 - zhou]
下面我们来看一下,外部比较器的实现。我们实现一个按照id来排序的比较器
class IdComparetor implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
if (o1.getId()< o2.getId())
return -1;
if (o1.getId()==o2.getId())
return 0;
if (o1.getId()> o2.getId())
return 1;
return 1;
}
}
并修改测试类。加上两段代码。
Collections.sort(list,new IdComparetor());
System.out.println(list);
运行结果为:
[4 - jim, 3 - kiki, 5 - sum, 2 - tom, 1 - zhou]
[1 - zhou, 2 - tom, 3 - kiki, 4 - jim, 5 - sum]