Comparable
Comparable 是排序接口,若一個類實現(xiàn)了 Comparable 接口,就意味著 “該類支持排序”。假設(shè)現(xiàn)在存在 “實現(xiàn) Comparable 接口的類的對象的集合(或數(shù)組)”,則該集合(或數(shù)組)可以通過 Collections.sort(或 Arrays.sort)進行排序。
Comparable 定義
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
實現(xiàn) Comparable 接口的類必須實現(xiàn) compareTo 方法,對象就可以比較大小。假設(shè)我們通過 x.compareTo(y) 來 “比較 x 和 y 的大小”。若返回 “負數(shù)”,意味著 “x 比 y 小”;返回 “零”,意味著 “x 等于 y”;返回 “正數(shù)”,意味著 “x 大于 y”。
public class Student implements Comparable {
String name;
public int compareTo(Student another) {
return name.compareTo(another.name);
}
}
// 比較兩個對象
student1.compareTo(student2);
// 排序數(shù)組或集合
Arrays.sort(students);
Collections.sort(collection);
Java 的一些常用類已經(jīng)實現(xiàn)了 Comparable 接口,并提供了比較大小的標(biāo)準(zhǔn)。比如包裝類按照它們對應(yīng)的數(shù)值大小進行比較。String,Date,Time 等也都實現(xiàn)了 Comparable 接口。一個類如果實現(xiàn) Comparable 接口,那么它就具有了可比較性。
分析比較器的排序原理
實際上比較器的操作,就是經(jīng)常聽到的二叉樹的排序算法。
排序的基本原理:使用第一個元素作為根節(jié)點,之后如果后面的內(nèi)容比根節(jié)點小,則放在左子樹,如果內(nèi)容比根節(jié)點的內(nèi)容要大,則放在右子樹。
Comparator
我們?nèi)粜枰刂颇硞€類的次序,而該類本身不支持排序(即沒有實現(xiàn) Comparable 接口);那么,我們可以建立一個 “該類的比較器” 來進行排序。這個 “比較器” 只需要實現(xiàn) Comparator 接口即可。
Comparator 定義
package java.util;
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
若一個類要實現(xiàn) Comparator 接口,它一定要實現(xiàn) compareTo(T o1, T o2) 函數(shù),但可以不實現(xiàn) equals(Object obj) 函數(shù)。Object 類是所有類的父類,也就是說實現(xiàn)接口的子類已經(jīng)重寫了 equals 方法。
int compare(T o1, T o2) 是 “比較 o1 和 o2 的大小”。返回 “負數(shù)”,意味著 “o1 比 o2 小”;返回 “零”,意味著 “o1 等于 o2”;返回 “正數(shù)”,意味著 “o1 大于 o2”。
在不希望修改一個原有的類,或提供的比較器不適用時,就需要使用外部比較器,比如 String 類實現(xiàn)
Comparable<String>,而且 String.compareTo() 是按字典序比較字符串的,這時如果需要按長度對字符串進行排序,就不能讓 String 類用兩種不同的方法實現(xiàn) compareTo 方法了,更何況,String 類也不應(yīng)該由我們來修改,這時就需要使用外部比較器:
class LengthComparator implements Comparator<String> {
public int compare(String f, String s) {
return f.length() - s.length();
}
}
// 比較兩個對象
LengthComparator comparator = new LengthComparator();
comparator.compare(person1,person2);
// 排序數(shù)組或集合
Arrays.sort(arr, new LengthComparator());
Collections.sort(collection, new LengthComparator());
Comparator 體現(xiàn)了策略模式,就是不改變對象自身,而用一個策略對象來改變它的行為。
Comparator 和 Comparable 區(qū)別
內(nèi)部比較器 Comparable 是排序接口,只包含一個函數(shù) compareTo();若一個類實現(xiàn)了 Comparable 接口,就意味著 “該類支持排序”,它可以直接通過 Arrays.sort() 或 Collections.sort() 進行排序。
外部比較器 Comparator 是比較器接口,單獨實現(xiàn)第一個比較器,不需要對原來的類進行結(jié)構(gòu)上的變化,屬于無侵入式的;一個類實現(xiàn)了 Comparator 接口,那么它就是一個 “比較器”。其它的類,可以根據(jù)該比較器去排序。
一個類本身實現(xiàn)了 Comparable 接口,就意味著它本身支持排序;若它本身沒實現(xiàn) Comparable,也可以通過外部比較器 Comparator 進行排序。
- 如果比較的方法只要用在一個類中,用該類實現(xiàn) Comparable 接口就可以。
- 如果比較的方法在很多類中需要用到,就自己寫個類實現(xiàn) Comparator 接口,這樣當(dāng)要比較的時候把實現(xiàn)了 Comparator 接口的類傳過去就可以,省得重復(fù)造輪子。這也是為什么 Comparator 會在 java.util 包下的原因。
使用 Comparator 的優(yōu)點:
- 與實體類分離
- 方便應(yīng)對多變的排序規(guī)則,可以同時使用多種排序標(biāo)準(zhǔn)