对对象的排序,可以通过以下两种方法:
- 实现Comparable接口,重写compareTo方法;
- Comparator比较器接口,重写compare方法;
Comparable接口
此接口只有一个方法
public int compareTo(T obj);
其中,T是泛型,需要指定具体的对象类型
接口中通过 x.compareTo(y)来比较x和y的大小
- x<y,返回负数;
- x=y,返回0;
- x>y,返回正数;
- 如果obj为null,则会抛出空指针异常
实现Comparable接口也需要指定具体的类型
public class Student implements Comparable<Student>{}
实现了该接口的类可以的数组或者List可以调用Arrays.sort()和Collections.sort()进行排序;
1 import java.util.Arrays; 2 3 4 public class Student implements Comparable<Student>{ 5 int age; 6 String number; 7 Student(int age, String number){ 8 //super(); 9 this.age = age; 10 this.number = new String(number); 11 } 12 Student(){ 13 //super(); 14 } 15 public String toString() { 16 return ("number:"+this.number+",age:"+this.age); 17 } 18 @Override 19 public int compareTo(Student o1) { 20 // TODO Auto-generated method stub 21 22 return o1.age-this.age; 23 } 24 public static void main(String[] args) { 25 Student stu0 = new Student(22,"3150103299"); 26 Student stu1 = new Student(21,"3170103299"); 27 Student stu2 = new Student(23,"3160103298"); 28 Student[] student = new Student[3]; 29 student[0]=stu0; 30 student[1]=stu1; 31 student[2]=stu2; 32 System.out.println("排序前:"); 33 for(Student stu:student) 34 System.out.println(stu.toString()); 35 Arrays.sort(student); 36 System.out.println("------------"); 37 System.out.println("排序后:"); 38 for(Student stu:student) 39 System.out.println(stu.toString()); 40 } 41 42 }
运行结果如图,实现了根据age进行排序:
Comparator比较器
Comparator 相当于一个比较器,作用和Comparable类似,也是使用Collections.sort() 和 Arrays.sort()来进行排序,也可以对SortedMap 和 SortedSet 的数据结构进行精准的控制,你可以不用实现此接口或者Comparable接口就可以实现次序比较。 TreeSet 和 TreeMap的数据结构底层也是使用Comparator 来实现。不同于Comparable ,比较器可以任选地允许比较null参数,同时保持要求等价关系。
Comparator比较器的方法,其中T为泛型,需要指定具体的类型;
int compare(T obj1, T obj2);
比较器实现Comparator方法的时候也需要指定具体类型
public class StudentComparator implements Comparator<Student>{}
实现了该接口的类可以的数组或者List可以调用Arrays.sort()和Collections.sort()进行排序;参数是数组或者list对象,以及比较器对象;
import java.util.Arrays; import java.util.Comparator; public class Student{ int age; String number; Student(int age, String number){ //super(); this.age = age; this.number = new String(number); } Student(){ //super(); } public String toString() { return ("number:"+this.number+",age:"+this.age); } } //构造比较器 class StudentComparator implements Comparator<Student>{ public int compare(Student stu1, Student stu2) { return stu1.age - stu2.age; } } public class Main{ public static void main(String[] args) { Student stu0 = new Student(22,"3150103299"); Student stu1 = new Student(21,"3170103299"); Student stu2 = new Student(23,"3160103298"); Student[] student = new Student[3]; student[0]=stu0; student[1]=stu1; student[2]=stu2; System.out.println("排序前:"); for(Student stu:student) System.out.println(stu.toString()); Arrays.sort(student,new StudentComparator()); System.out.println("------------"); System.out.println("排序后:"); for(Student stu:student) System.out.println(stu.toString()); } }
运行结果如图:
两者区别:
- Comparable接口和类的耦合性高。就是说一个类实现了Comparable 接口,重写了compareTo()方法,那么它就可以被排序;
- 但是如果一个类没有实现Comparable接口,我们又无法对那个类进行改变,要实现排序的话,就可以使用Comparator接口;通过建立一个“该类的比较器”来进行排序(其实也是重新写一个类,这个类实现了Comparator接口,重写了compare()方法。
- compareTo()不接受null作为入参,compare()可以接受null作为入参,但要求保持等价关系