java comparator和comparable

有兩種方式可以進行集合排序 :

  1. 集合中對象的所屬類實現了 java.lang.Comparable 接口
  2. 爲集合指定比較器 java.lang.Comparator 的實現類

1. java.lang.Comparable

public interface Comparable 接口強行對實現它的每個類的對象進行整體排序。 -- 自然排序。類的compareTo稱爲自然比較方法。

這個接口的作用?
若一個類實現了Comparable 接口,實現 Comparable 接口的類的對象的 List 列表 ( 或數組)可以通過 Collections.sort(或 Arrays.sort)進行排序。
此外,實現 Comparable 接口的類的對象 可以用作 “有序映射 ( 如 TreeMap)” 中的鍵或 “有序集合 (TreeSet)” 中的元素,而不需要指定比較器。

如何實現?
利用Comparable接口創建自己的類的排序順序,只是實現comparaTo方法的問題。
通常就是依賴幾個數據成員的自然排序。同時類也應該覆蓋equals()和hashCode() 以確保兩個相等的對象返回同一個哈希碼。

Comparable接口只有一個方法,compareTo(Object obj),定義如下:

public interface Comparable<T> {
    public int compareTo(T o);
}

通常需要覆寫 compareTo 方法實現排序規則的應用 : int compareTo(Object o): 比較當前實例對象與對象 o ,如果位於對象 o 之前,返回負值,如果兩個對象在排序中位置相同,則返回 0 ,如果位於對象 o 後面,則返回正值。

在 Java 2 SDK 版本 1.4 中有24個類實現 Comparable 接口。下表展示了 8 種基本類型的自然排序。雖然一些類共享同一種自然排序,但只有相互可比的類才能排序。

排序
BigDecimal,BigInteger,Byte,Double, Float,Integer,Long,Short
按數字大小排序
Character
按 Unicode 值的數字大小排序
String
按字符串中字符 Unicode 值排序

舉個例子:
覆寫compareTo : 設計一個有序Person類,實現了Comparable接口, 以年齡爲第一關鍵字,姓名爲第二關鍵字升序排序。

 public int compareTo(Person person) {
       int cop = age - person.getAge();
       if (cop != 0)
           return cop;
       else
           return name .compareTo(person. name );
    }

再舉個例子,設計有序Person類,以id爲關鍵字:
//實現Comparable接口的抽象方法,定義排序規則

public int compareTo(Object o){
  Person per = (Person)o;
  return this.id - per.id;
}

2. Comparator 比較器接口(策略設計模式)

我們如果需要控制某個類的次序,而該類本身不支持排序(即沒有實現Comparable接口);那麼可以建立一個該類的比較器來排序,這個比較器只需要實現Comparator接口即可。
namely, 通過實現Comparator類來新建一個比較器,然後通過該比較器來對類進行排序。Comparator 接口其實就是一種策略模式的實踐

接口作用?
1.如果一個類已經開放完成,但是在此類建立的初期並沒有實現 Comparable 接口,此時肯定是無法進行對象排序操作的,所以爲了解決這一的問題,java 又定義了另一個比較器的操作接口 Comparator 此接口定義在 java.util 包中
2. 爲了使用不同的排序標準做準備,比如升序,降序或者其他什麼序列

如何定義?
接口僅僅包括兩個函數

package java.util;

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
 }
  1. 若一個類要實現Comparator接口:它一定要實現compare(T o1, T o2)函數,但是可以不實現equals函數。
    爲什麼可以不實現 equals(Object obj) 函數呢? 因爲任何類,默認都是已經實現了 equals(Object obj) 的。 Java 中的一切類都是繼承於 java.lang.Object,在 Object.java 中實現了 equals(Object obj) 函數;所以,其它所有的類也相當於都實現了該函數。

  2. int compare(T o1, T o2) 是 “比較 o1 和 o2 的大小”。返回 “負數”,意味着 “o1 比 o2 小”;返回 “零”,意味着 “o1 等於 o2”;返回 “正數”,意味着 “o1 大於 o2”。

舉個例子,Student例子已經寫完,但是想根據age進行排序

Student stu[] = {
                  new Student("張三" ,23),
                  new Student("李四" ,26)
                  , new Student("王五" ,22)}; 
Arrays. sort(stu,new MyComparator());   

List<Student> list = new ArrayList<Student>(); 
list.add( new Student("zhangsan" ,31)); 
list.add( new Student("lisi" ,30)); 
list.add( new Student("wangwu" ,35)); 
Collections. sort(list,new MyComparator());

3.Comparable 和 Comparator比較

Comparable 是排序接口;若一個類實現了 Comparable 接口,就意味着 “該類支持排序”。
而 Comparator 是比較器;我們若需要控制某個類的次序,可以建立一個 “該類的比較器” 來進行排序。

前者應該比較固定,和一個具體類相綁定,而後者比較靈活,它可以被用於各個需要比較功能的類使用。可以說前者屬於 “靜態綁定”,而後者可以 “動態綁定”。

我們不難發現:Comparable 相當於 “內部比較器”,而 Comparator 相當於 “外部比較器”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章