Java 比較器 Comparable 與 Comparator

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):

  1. 與實(shí)體類分離
  2. 方便應(yīng)對多變的排序規(guī)則枚驻,可以同時使用多種排序標(biāo)準(zhǔn)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末濒旦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子再登,更是在濱河造成了極大的恐慌尔邓,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锉矢,死亡現(xiàn)場離奇詭異梯嗽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沽损,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門灯节,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绵估,你說我怎么就攤上這事炎疆。” “怎么了国裳?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵形入,是天一觀的道長。 經(jīng)常有香客問我躏救,道長唯笙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任盒使,我火速辦了婚禮崩掘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘少办。我一直安慰自己苞慢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布英妓。 她就那樣靜靜地躺著挽放,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔓纠。 梳的紋絲不亂的頭發(fā)上辑畦,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機(jī)與錄音腿倚,去河邊找鬼纯出。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的暂筝。 我是一名探鬼主播箩言,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼焕襟!你這毒婦竟也來了陨收?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤鸵赖,失蹤者是張志新(化名)和其女友劉穎务漩,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卫漫,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡菲饼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了列赎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宏悦。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖包吝,靈堂內(nèi)的尸體忽然破棺而出饼煞,到底是詐尸還是另有隱情,我是刑警寧澤诗越,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布砖瞧,位于F島的核電站,受9級特大地震影響嚷狞,放射性物質(zhì)發(fā)生泄漏块促。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一床未、第九天 我趴在偏房一處隱蔽的房頂上張望竭翠。 院中可真熱鬧,春花似錦薇搁、人聲如沸斋扰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽传货。三九已至,卻和暖如春宏娄,著一層夾襖步出監(jiān)牢的瞬間问裕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工孵坚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粮宛,地道東北人貌踏。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像窟勃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逗堵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在秉氧,面了一些公司,掛了不少蜒秤,但最終還是拿到小米汁咏、百度、阿里作媚、京東攘滩、新浪、CVTE纸泡、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,218評論 11 349
  • 項(xiàng)目中經(jīng)常會遇到列表搜索查詢漂问,大部分的查詢是可以通過sql語句來實(shí)現(xiàn)的,有些特殊的搜索排序sql則實(shí)現(xiàn)不了女揭,例如中...
    信徒_allen閱讀 2,580評論 0 1
  • Java集合框架 Java平臺提供了一個全新的集合框架蚤假。“集合框架”主要由一組用來操作對象的接口組成吧兔。不同接口描述...
    小石38閱讀 359評論 0 0
  • 某天老板說:要不這個改成這個吧磷仰,雨聲,你怎么看境蔼?運(yùn)營說:雨聲灶平,你輸了,看看人家的設(shè)計箍土!商務(wù)說:商家說逢享,“官人,人家...
    雨聲閱讀 624評論 0 51
  • 感賞自己早上起來涮帘,看到兒子正在擺弄手機(jī)拼苍,但沒玩游戲,盡管心里有厭煩调缨,神情還是很自然疮鲫。我平生最討厭早上一起床,就打開...
    玫瑰鏗鏘閱讀 171評論 0 1