Java中的comparable和comparator接口

概念:

        Comparable & Comparator 都是用來實現集合中元素的比較、排序的,只是 Comparable 是在集合內部定義的方法實現的排序,Comparator是在集合外部實現的排序,所以,如想實現排序,就需要在集合外定義 Comparator 接口的方法 或 在集合內實現 Comparable 接口的方法。

       其中,comparable位於java.util下,comparator位於java.lang中。

       Comparable是一個對象本身就已經支持自比較所需要實現的接口,如String、Integer自己就實現了Comparable接口,可完成比較大小操作。自定義類要在加入list容器中後能夠排序,也可以實現Comparable接口,在用Collections類的sort方法排序時若不指定Comparator,那就以自然順序排序。所謂自然順序就是實現Comparable接口設定的排序方式。
       Comparator是一個專用(自定義)的比較器,當這個對象使用默認的比較方式不能滿足要求時,可寫一個比較器來完成兩個對象之間大小的比較。Comparator體現了一種策略模式(strategy design pattern),就是不改變對象自身,而用一個策略對象(strategy object)來改變它的行爲。

使用:

Comparable 簡單, 只要實現 Comparable 接口的對象直接就成爲一個可以比較的對象,但是需要修改源代碼。 
適用於: 在不同場景只對自定義對象按同種形式進行排序。(例如:在項目需求中,只需要對Person對象按年齡排序)
Comparator 的好處是使用靈活,不需要修改源代碼, 而是另外實現一個比較器, 當某個自定義的對象需要作比較的時候,把比較器和對象一起傳遞過去就可以比大小了, 並且在Comparator 裏面用戶可以自己實現複雜的可以通用的邏輯,使其可以匹配一些比較簡單的對象,那樣就可以節省很多重複勞動了(類似策略模式的優點)。 

(1)Comparable:

實現Comparable接口要覆蓋compareTo方法, 在compareTo方法裏面實現比較:

public class Person implements Comparable { 
     String name; 
     int age 
     public int compareTo(Person another) { 
          int i = 0; 
          i = name.compareTo(another.name); // 使用字符串的比較 
          if(i == 0) { // 如果名字一樣,比較年齡, 返回比較年齡結果 
               return age - another.age; 
          } else { 
               return i; // 名字不一樣, 返回比較名字的結果. 
          } 
     } 
}

 這時我們可以直接用 Collections.sort( personList ) 對其排序了.

(2)Comparator

實現Comparator需要覆蓋 compare 方法:

//需要排序的類
public class Person{ 
     String name; 
     int age 
}

//再類的外部定義比較器
class PersonComparator implements Comparator { 
     public int compare(Person one, Person another) {
          int i = 0;
          i = one.name.compareTo(another.name); // 使用字符串的比較
          if(i == 0) { // 如果名字一樣,比較年齡,返回比較年齡結果
               return one.age - another.age;
          } else {
               return i; // 名字不一樣, 返回比較名字的結果.
          }
     }
}

示例:

《劍指offer》題目:

輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。

import java.util.ArrayList;
import java.util.*;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        //直接利用字符串數組的排序  再將其拼接在一起
        //在排序時,本題目用到了比較器comparator的複寫
        String[] str = new String [numbers.length];
        for(int i=0; i<numbers.length; i++){
            str[i] = String.valueOf(numbers[i]);
        }
        Arrays.sort(str,new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
                String c1 = s1 + s2;
                String c2 = s2 + s1;
                return c1.compareTo(c2);
                //此處的compareTo是String中本身就繼承的comparable接口,可以用於直接比較
            }
        });
        String temp = "";
        for(int i=0;i<numbers.length;i++){
            temp+=str[i];
        }
        return temp;
    }
}

上題中,在比較字符串組合的大小時,無法直接使用默認的comparable比較器,因此在比較是重新定義了一個比較器comparator後,再調用的Arrays.sort(str,new comparator{}),在這裏可以學習一下這種構造器的定義方法,在Arrays.sort中直接定義:

Arrays.sort(str,new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
                String c1 = s1 + s2;
                String c2 = s2 + s1;
                return c1.compareTo(c2);
                //此處的compareTo是String中本身就繼承的comparable接口,可以用於直接比較
            }
        });


本文參考:https://blog.csdn.net/acema/article/details/7513269 ; https://blog.csdn.net/l_lhc/article/details/50596065

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