對象排序之Comparator,Comparable接口區別

現有一個類person有三個屬性,分別是name,age,sex。有一個List對象,保存了很多person對象的實例,請編寫一個函數,對List裏的實例進行排序。條件:18歲以上的人,排序順序:性別,年齡,姓名全部降序。

給了個類,要求編寫一段代碼,給以下類型的數據排序(按index降序排): 
public class A{ 
  public int index ;  
  public String str; 
  public …… ; 

條件: 
1.數據量很大,要求性能夠; 
2.擴展性好:按其他數據類型(如 String str,……)排序的時候,不需要修改組件,以後還可能增加其他類型的數據。 
(提示:可以調用現成的Java.util包中的排序.) 

對象排序之Comparator,Comparable接口區別: 

1.comparable是通用的接口,用戶可以實現它來完成自己特定的比較,而comparator可以看成一種算法的實現,在需要容器集合 collection需要比較功能的時候,來指定這個比較器,這可以看出一種設計模式(策略模式Strategy),將算法和數據分離,就像C++ STL中的函數對象一樣。 
2.前者應該比較固定,和一個具體類相綁定,而後者比較靈活,它可以被用於各個需要比較功能的類使用。可以說前者屬於“靜態綁定”,而後者可以“動態綁定”。 
3.一個類實現了Camparable接口表明這個類的對象之間是可以相互比較的。如果用數學語言描述的話就是這個類的對象組成的集合中存在一個全序。這樣,這個類對象組成的集合就可以使用Sort方法排序了。 
4.而Comparator的作用有兩個: 
 a,如果類的設計師沒有考慮到Compare的問題而沒有實現Comparable接口,可以通過Comparator來實現比較算法進行排序 
 b,可以更加靈活實現排序規則,爲了使用不同的排序標準做準備,比如:升序、降序,或者將來想通過類的其他字段進行排序 

Name類,實現comparable接口來對對象進行排序: 

  1. public class Name implements Comparable<Name>{  
  2.  public String firstName, lastName, id;  
  3.     
  4.  public Name(String firstName,String lastName,String id){  
  5.           this.firstName=firstName;  
  6.           this.lastName=lastName;  
  7.           this.id=id;  
  8.       }  
  9.      public int compareTo(Name o) {          //重寫  
  10.           int lastCmp=lastName.compareTo(o.lastName);  
  11.           return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));  
  12.       }     
  13.      public String toString(){                //便於輸出測試  
  14.           return firstName+" "+lastName;  
  15.       }  
  16. }  

NameSort類,測試 
  1. import java.util.*;  
  2. public class NameSort {  
  3.  public static void main(String[] args) {  
  4.   // TODO Auto-generated method stub  
  5.    Name[] nameArray = new Name[]{  
  6.                 new Name("John""Lennon","3556465464644343"),  
  7.                 new Name("Karl""Marx","3556465461111111"),  
  8.                 new Name("Groucho""Marx","3805236412578"),  
  9.                 new Name("Oscar""Grouch","8854321622238")  
  10.             };  
  11.             Arrays.sort(nameArray);  
  12.             for(int i=0;i<nameArray.length;i++){  
  13.                 System.out.println(nameArray[i].toString());  
  14.             }  
  15.  }  
  16. }  

更加靈活的是方式是實現Comparator接口,使用Collections.sort(List<T> list, Comparator<? super T> c)這個方法進行排序: 
FIRST_NAME_ORDER類 
  1. import java.util.*;  
  2. public class FIRST_NAME_ORDER implements Comparator<Name>{  
  3.  public int compare(Name n1, Name n2) {  
  4.         int firstCmp=n1.firstName.compareTo(n2.firstName);  
  5.         return (firstCmp!=0?firstCmp:n1.lastName.compareTo  
  6.                 (n2.firstName));  
  7.  }  
  8. }  
在上面的NameSort中將 Arrays.sort(nameArray);替換成下面語句 
  1. List<Name> list=Arrays.asList(nameArray); //將名字數組轉化爲List  
  2. Collections.sort(list,new FIRST_NAME_ORDER());  
總結: 
1.這裏自定義FIRST_NAME_ORDER,通過Collections.sort(List,Comparator)實現排序,當需求有變需要按照其他規則(比如id)排序時,只有重新定義一個Comaprator----ID_ORDER_Comparator,而不用修改Name或原來的排序器FIRST_NAME_ORDER,然後修改客戶端代碼,只有就基本滿足了程序設計的一個重要原則---開閉原則,即可以通過增加新類方便的擴充新功能,滿足新需求而不用修改原來的代碼。 
2.如果我們採用讓Name實現Comaparable接口,則在想採用新的排序規則時,必須修改Name裏的 comareTo(Object o)方法,這樣就違反了開閉原則,所以應該用Comparator,而不是Comparable.
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章