Collections的静态sort方法只能对Java中某些默认的类型进行升序排序,如int,String。当我们尝试在存储自定义类的集合中使用这个方法会发现失效。
我们必须重写Comparable或Comparator接口中的方法,才能定义我们的自定义类集合的排序顺序。
Comparable:
Comparable比较器是在自定义类中实现Comparable接口,并重写compareTo方法,下面我们自定义一个Person类:
public class Person implements Comparable<Person> {//接口实现
private int age;
private String name;
public Person() {
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Person o) {//重写方法
return this.getAge() - o.getAge();//按年龄升序
//this.getAge() - o.getAge();按年龄降序
}
}
此类中重写了compareTo方法,以后sort排序该类都按年龄升序排序
那么问题来了,如果我用该类new了两个对象一个按照年龄升序,另一个想按照年龄降序,用此种比较器就没有办法做到了,于是我们可以用另一种比较器
Comparator:
该比较器是在调用sort方法的同时传送一个实现Comparator接口匿名内部类对象,在内部类重写中重写compara方法
下面定义一个Student类:
public class Student {
private int Num;
private String Name;
Student(){
}
Student(int num,String name){
this.Num = num;
this.Name = name;
}
public int getNum(){
return Num;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public void setNum(int Num){
this.Num = Num;
}
@Override
public String toString() {
return "Student{" +
"Num=" + Num +
", Name='" + Name + '\'' +
'}';
}
}
然后我们再Demo以下
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
Student s1 = new Student(10001,"陈强");
Student s2 = new Student(10002,"正蠡");
Student s3 = new Student(10004,"黄渤");
Student s4 = new Student(10003,"尚昆");
Collections.addAll(list,s1,s2,s3,s4);
System.out.println("排序前" + list);//未排序输出
Collections.sort(list,new Comparator<Student>(){//排序,传一个匿名内部类,重写compare()方法
@Override
public int compare(Student o1, Student o2) {
return o1.getNum() - o2.getNum();//按学号升序
}
});
System.out.println("排序后" + list);//排序后输出
}
}
输出结果:
排序前[Student{Num=10001, Name='陈强'}, Student{Num=10002, Name='正蠡'}, Student{Num=10004, Name='黄渤'}, Student{Num=10003, Name='尚昆'}]
排序后[Student{Num=10001, Name='陈强'}, Student{Num=10002, Name='正蠡'}, Student{Num=10003, Name='尚昆'}, Student{Num=10004, Name='黄渤'}]
总结:Comparator接口比Comparable更加灵活,如果同一个类实例出的不同对象要有不同的排序方法,就选择前者。