對對象的排序,可以通過以下兩種方法:
- 實現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作為入參,但要求保持等價關系