Comparable
Comparable 是排序接口咧纠,若一個類實(shí)現(xiàn)了 Comparable 接口,就意味著 “該類支持排序”揭绑。假設(shè)現(xiàn)在存在 “實(shí)現(xiàn) Comparable 接口的類的對象的集合(或數(shù)組)”怜庸,則該集合(或數(shù)組)可以通過 Collections.sort(或 Arrays.sort)進(jìn)行排序砖织。
Comparable 定義
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
實(shí)現(xiàn) Comparable 接口的類必須實(shí)現(xiàn) compareTo 方法,對象就可以比較大小娇哆。假設(shè)我們通過 x.compareTo(y) 來 “比較 x 和 y 的大小”湃累。若返回 “負(fù)數(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)實(shí)現(xiàn)了 Comparable 接口,并提供了比較大小的標(biāo)準(zhǔn)溉躲。比如包裝類按照它們對應(yīng)的數(shù)值大小進(jìn)行比較榜田。String,Date锻梳,Time 等也都實(shí)現(xiàn)了 Comparable 接口箭券。一個類如果實(shí)現(xiàn) Comparable 接口,那么它就具有了可比較性疑枯。
分析比較器的排序原理
實(shí)際上比較器的操作辩块,就是經(jīng)常聽到的二叉樹的排序算法。
排序的基本原理:使用第一個元素作為根節(jié)點(diǎn)荆永,之后如果后面的內(nèi)容比根節(jié)點(diǎn)小废亭,則放在左子樹,如果內(nèi)容比根節(jié)點(diǎn)的內(nèi)容要大具钥,則放在右子樹豆村。
Comparator
我們?nèi)粜枰刂颇硞€類的次序,而該類本身不支持排序(即沒有實(shí)現(xiàn) Comparable 接口)骂删;那么掌动,我們可以建立一個 “該類的比較器” 來進(jìn)行排序。這個 “比較器” 只需要實(shí)現(xiàn) Comparator 接口即可宁玫。
Comparator 定義
package java.util;
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
若一個類要實(shí)現(xiàn) Comparator 接口粗恢,它一定要實(shí)現(xiàn) compareTo(T o1, T o2) 函數(shù),但可以不實(shí)現(xiàn) equals(Object obj) 函數(shù)欧瘪。Object 類是所有類的父類眷射,也就是說實(shí)現(xiàn)接口的子類已經(jīng)重寫了 equals 方法。
int compare(T o1, T o2) 是 “比較 o1 和 o2 的大小”。返回 “負(fù)數(shù)”妖碉,意味著 “o1 比 o2 小”涌庭;返回 “零”,意味著 “o1 等于 o2”嗅绸;返回 “正數(shù)”脾猛,意味著 “o1 大于 o2”。
在不希望修改一個原有的類鱼鸠,或提供的比較器不適用時猛拴,就需要使用外部比較器,比如 String 類實(shí)現(xiàn)
Comparable<String>蚀狰,而且 String.compareTo() 是按字典序比較字符串的愉昆,這時如果需要按長度對字符串進(jìn)行排序,就不能讓 String 類用兩種不同的方法實(shí)現(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()堪侯;若一個類實(shí)現(xiàn)了 Comparable 接口,就意味著 “該類支持排序”荔仁,它可以直接通過 Arrays.sort() 或 Collections.sort() 進(jìn)行排序伍宦。
外部比較器 Comparator 是比較器接口,單獨(dú)實(shí)現(xiàn)第一個比較器乏梁,不需要對原來的類進(jìn)行結(jié)構(gòu)上的變化次洼,屬于無侵入式的;一個類實(shí)現(xiàn)了 Comparator 接口遇骑,那么它就是一個 “比較器”卖毁。其它的類,可以根據(jù)該比較器去排序落萎。
一個類本身實(shí)現(xiàn)了 Comparable 接口势篡,就意味著它本身支持排序;若它本身沒實(shí)現(xiàn) Comparable模暗,也可以通過外部比較器 Comparator 進(jìn)行排序。
- 如果比較的方法只要用在一個類中念祭,用該類實(shí)現(xiàn) Comparable 接口就可以兑宇。
- 如果比較的方法在很多類中需要用到,就自己寫個類實(shí)現(xiàn) Comparator 接口粱坤,這樣當(dāng)要比較的時候把實(shí)現(xiàn)了 Comparator 接口的類傳過去就可以隶糕,省得重復(fù)造輪子瓷产。這也是為什么 Comparator 會在 java.util 包下的原因。
使用 Comparator 的優(yōu)點(diǎn):
- 與實(shí)體類分離
- 方便應(yīng)對多變的排序規(guī)則枚驻,可以同時使用多種排序標(biāo)準(zhǔn)