對物件的排序,可以通過以下兩種方法:
1、實現Comparable介面,重寫compareTo方法;
2、Comparator<>比較器介面,重寫compare方法;
區別:Comparator位於包java.util下,而Comparable位於包java.lang下,Comparable介面將比較程式碼嵌入自身類中,而後者在一個獨立的類中實現比較。
(1)Comparator比較器介面
想要對一個類的物件進行排序,需要寫一個實現類實現此介面,呼叫Arrays.sort()或Collection.sort()進行排序,先重寫Comparator<>的實現類中的compare方法,然後將排序的規則寫在方法中。
compare(T o1,T o2)方法排序規則:
例如比較年齡:
o1.getAge()>o2.getAge()返回 1,
o1.getAge()<o2.getAge()返回 -1,
相等返回0,可繼續通過其它屬性來比較
最後會按照年齡從小到大來輸出。
下面舉例比較員工類Emps:
1、先寫一個員工類
1 package comparator; 2 3 public class Emps { 4 private String name; 5 private int age; 6 private int sal; 7 public Emps(String name, int age, int sal) { 8 this.name = name; 9 this.age = age; 10 this.sal = sal; 11 } 12 public Emps() {} 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 this.name = name; 18 } 19 public int getAge() { 20 return age; 21 } 22 public void setAge(int age) { 23 this.age = age; 24 } 25 public int getSal() { 26 return sal; 27 } 28 public void setSal(int sal) { 29 this.sal = sal; 30 } 31 @Override 32 public String toString() { 33 return "Emp [ename=" + name + ", age=" + age + ", sal=" + sal + "]"; 34 } 35 }
2、然後是實現類EmpsComparator
1 package comparator; 2 import java.util.Comparator; 3 4 public class EmpsComparator implements Comparator<Emps> { 5 @Override 6 public int compare(Emps o1, Emps o2) { 7 //比較年齡 8 if(o1.getAge()>o2.getAge()){ 9 return 1; 10 }else if(o1.getAge()<o2.getAge()){ 11 return -1; 12 }else{ 13 //年齡相同,比較工資 14 if(o1.getSal()>o2.getSal()){ 15 return 1; 16 }else if(o1.getSal()<o2.getSal()){ 17 return -1; 18 } 19 } 20 return 0; 21 } 22 }
3、測試
1 package comparator; 2 import java.util.Arrays; 3 4 public class Test { 5 public static void main(String[] args) { 6 Emps[] emps={ 7 new Emps("佐菲",35,30000),//姓名,年齡,工資 8 new Emps("賽文",33,28000), 9 new Emps("傑克",33,25000), 10 new Emps("艾斯",32,24000), 11 new Emps("泰羅",30,22000), 12 }; 13 Arrays.sort(emps,new EmpsComparator()); 14 for (Emps e:emps) { 15 System.out.println(e); 16 } 17 } 18 }
4、輸出
上面程式碼是通過Arrays.sort(emps,new EmpsComparator())進行排序的,若沒有new EmpsComparator()比較規則會顯示ClassCastException異常,這預設是從小到大排序的,若想從大到小,只需將返回值1和-1調換。
(2)Comparable介面
此介面強行對實現它的每個類的物件進行整體排序。此排序被稱為該類的自然排序 ,類的 compareTo
方法被稱為它的自然比較方法 。實現此介面的物件列表(和陣列)可以通過 Collections.sort
(和 Arrays.sort
)進行自動排序。
1 package comparator; 2 3 public class Emp implements Comparable<Emp>{ 4 private String name; 5 private int age; 6 private int sal; 7 8 @Override 9 public int compareTo(Emp o) { 10 //比較年齡 11 if(this.getAge()>o.getAge()){ 12 return 1; 13 }else if(this.getAge()<o.getAge()){ 14 return -1; 15 }else{ 16 //年齡相同,比較工資 17 if(this.getSal()>o.getSal()){ 18 return 1; 19 }else if(this.getSal()<o.getSal()){ 20 return -1; 21 } 22 } 23 return 0; 24 } 25 26 public Emp(String name, int age, int sal) { 27 this.name = name; 28 this.age = age; 29 this.sal = sal; 30 } 31 public Emp() { 32 } 33 public String getName() { 34 return name; 35 } 36 public void setName(String name) { 37 this.name = name; 38 } 39 public int getAge() { 40 return age; 41 } 42 public void setAge(int age) { 43 this.age = age; 44 } 45 public int getSal() { 46 return sal; 47 } 48 public void setSal(int sal) { 49 this.sal = sal; 50 } 51 @Override 52 public String toString() { 53 return "Emp [ename=" + name + ", age=" + age + ", sal=" + sal + "]"; 54 } 55 56 57 } 58 package comparator; 59 import java.util.Arrays; 60 public class Test { 61 public static void main(String[] args) { 62 Emp[] emps={ 63 new Emp("佐菲",35,30000), 64 new Emp("賽文",33,28000), 65 new Emp("傑克",33,25000), 66 new Emp("艾斯",32,24000), 67 new Emp("泰羅",30,22000), 68 }; 69 Arrays.sort(emps); 70 for (Emp e:emps) { 71 System.out.println(e); 72 } 73 } 74 }
此介面只需用要排序的類來實現它,然後重寫compareTo方法即可,關於這個方法裡面是用本類物件和其他類物件進行比較,然後測試類中只需寫Arrays.sort(emps);即可比較的規則跟Comparator相同
int compareTo(T o) 比較此物件與指定物件的順序。如果該物件小於、等於或大於指定物件,則分別返回負整數、零或正整數。
4、介面總結
讓規範和實現分離正是介面的好處,讓系統的各元件之間通過介面耦合,是一種鬆耦合的設計。軟體系統各模組之間也應該採用這種面向介面的耦合,為系統提供更好的可擴充套件性和維護性。
抽象類與介面的區別
1、組成上:抽象類=普通類的組成+【抽象方法】,介面中只能包含抽象方法,常量,靜態方法、預設方法。
2、抽象類和介面均不能直接例項化。
3、介面看成是對抽象類的再次抽象。
4、抽象類受到繼承單根性的限制,介面可以多繼承。
5、介面可以更好的實現多型。介面一般用於系統間的解耦。一般情況使用面向介面程式設計。
6、介面不包含建構函式;抽象類可以包含建構函式,抽象類裡的建構函式並不是用於建立物件,而是讓其子類呼叫這些建構函式來完成屬於抽象類的初始化操作。
7、能用介面地方儘量使用而不要使用抽象類。
8、抽象類一般用於模板設計、介面卡設計。
今天就總結到這了,下週繼續!!!!!奧裡給!!!