Java排序方式對(duì)比分析

? ? 對(duì)于集合來說盛末,排序是一個(gè)很常見的操作抖锥,Java已經(jīng)提供了一系列排序的方法登舞,如Collections中的靜態(tài)方法public static void sort(List list, Comparator c); List接口提供的default? void sort(Comparator c); Java Stream提供的sorted(Comparator c) 菲驴,只需要傳入滿足排序規(guī)則的Comparator,就可以輕松的完成排序错英;然而入撒,遺憾的是,作為排序操作之中最重要最關(guān)鍵的排序規(guī)則構(gòu)造椭岩,即Comparator的構(gòu)造茅逮,原生的Java庫并沒有提供相對(duì)簡單易懂的構(gòu)造工具和方法。

? ? 一些第三方的工具庫已經(jīng)對(duì)此不足判哥,做了相應(yīng)的補(bǔ)充献雅,其中比較具有知名度,并且簡單易用的有Guava的Ordering姨伟、Apache工具類提供的比較器構(gòu)造方法惩琉。本篇文章也主要是圍繞這兩者提供的Comparator構(gòu)造方法進(jìn)行介紹和比較進(jìn)行展開,詳細(xì)介紹兩種方法的優(yōu)點(diǎn)夺荒。

? ? 我們平時(shí)需要用到的復(fù)雜排序規(guī)則主要會(huì)有瞒渠,倒序、自然數(shù)大小排序技扼,字典大小排序伍玖、多規(guī)則排序鏈(第一排序、第二排序......)等剿吻。下面比較Java原生的Comparator構(gòu)造方法窍箍、Guava的Ordering、Apache工具類提供的構(gòu)造Comparator方法丽旅,說明是Guava的Ordering椰棘、Apache工具類怎么簡單、靈活解決滿足這些排序規(guī)則的榄笙。

一邪狞、Apache工具類ComparableComparator、ComparatorUtils茅撞、ComparatorChain

ComparableComparator.getInstance ();

ComparatorUtils.naturalComparator();

均能提供一個(gè)自然排序的Comparator(數(shù)字從小到大排序帆卓、字典排序),這個(gè)是復(fù)雜Comparator構(gòu)造的基礎(chǔ)米丘。

個(gè)人認(rèn)為Guava和Apache構(gòu)造Comparator都有用到裝飾者設(shè)計(jì)模式的思想剑令,先構(gòu)造出最基本的自然排序Comparator,再一層一層裝飾上其他的排序規(guī)則拄查。

Apache里面構(gòu)造復(fù)雜比較規(guī)則的方法主要在ComparatorUtils和BeanComparator吁津。

BeanComparator構(gòu)造的比較器可以用類對(duì)象里面的property字段按照傳入的comparator比較器規(guī)則進(jìn)行排序。

BeanComparator(String property, Comparator comparator)

ComparatorUtils則提供一系列裝飾排序規(guī)則的方法;

多規(guī)則排序鏈(第一排序堕扶、第二排序......):

public static Comparator chainedComparator(Comparator[] comparators)腺毫;

倒序排序

public static Comparator reversedComparator(Comparator comparator)癣疟;

集合中有Null值,Null放置在排序序列的前面潮酒;

public static Comparator nullHighComparator(Comparator comparator);

相反的邪蛔,集合中有Null值急黎,Null放置在排序序列的后面;

public static Comparator nullLowComparator(Comparator comparator)侧到;

對(duì)比較對(duì)象做處理勃教,Transformer返回值進(jìn)行排序,類似于BeanComparator(String property, Comparator comparator)匠抗,添加了復(fù)雜性故源,但更處理比較對(duì)象的自由度也更高。

public static Comparator transformedComparator(Comparator comparator, Transformer transformer)汞贸;

其他不屬于構(gòu)造比較器的方法绳军,根據(jù)比較規(guī)則獲取最小\最大對(duì)象。

public static Object min(Object o1, Object o2, Comparator comparator);

public static Object max(Object o1, Object o2, Comparator comparator);

二矢腻、Guava的Ordering

? ? Ordering是Guava流暢風(fēng)格比較器[Comparator]的實(shí)現(xiàn)门驾,它可以用來為構(gòu)建復(fù)雜的比較器,以完成集合排序的功能多柑。從實(shí)現(xiàn)上說奶是,Ordering extends Comparator,提供了鏈?zhǔn)秸{(diào)用方法竣灌,來定制和增強(qiáng)現(xiàn)有的比較器聂沙。其中鏈?zhǔn)秸{(diào)用構(gòu)造Ordering ( extends Comparator)是Ordering相對(duì)于Apache工具類構(gòu)造Comparator來說最大的特色,提高了構(gòu)造的簡潔和易用性初嘹,個(gè)人喜歡這種風(fēng)格去構(gòu)造Comparator及汉。

類似的,Ordering也提供了基礎(chǔ)的自然排序Ordering

public static Ordering natural();

添加了按對(duì)象的字符串形式做字典排序的基礎(chǔ)Ordering

public static Ordering usingToString();

更提供了將普通Comparator轉(zhuǎn)化成Ordering的方法削樊,這也提供了Java原生Comparator構(gòu)造豁生、Apache工具類構(gòu)造和Ordering構(gòu)造混用的可能,能夠?qū)σ延械腃omparator進(jìn)行加強(qiáng)漫贞、裝飾甸箱。

public static Ordering from(Comparator comparator);

下面是Ordring提供構(gòu)造復(fù)雜Ordering的方法;

多規(guī)則排序鏈(第一排序迅脐、第二排序......);

public Ordering compound(Comparator secondaryComparator);

public static Ordering compound(Iterable?comparators);

按照給定的順序進(jìn)行排序芍殖。

public static Ordering explicit(List valuesInOrder);

倒序排序

public Ordering reverse();

null值在前面排序

public Ordering nullsFirst();

null值在后面排序

publicOrdering nullsLast();

對(duì)比較對(duì)象做處理,按Function 返回值進(jìn)行排序谴蔑;

public Ordering onResultOf(Function function)豌骏;

其他不屬于構(gòu)造比較器的方法:

根據(jù)比較規(guī)則獲取最小\最大對(duì)象龟梦。

public?E min(Iterable iterable)

public?E max(Iterable iterable)

根據(jù)比較規(guī)則獲取最小\最大k個(gè)對(duì)象。

public List greatestOf(Iterable iterable,int k);

public List leastOf(Iterable iterable,int k);

? ? 前面提到窃躲,Ordering也使用到了裝飾者設(shè)計(jì)思想计贰,可以看到Ordering構(gòu)造方法都不用傳入被裝飾的ordering,這是因?yàn)镺rdering鏈?zhǔn)秸{(diào)用的好處蒂窒,直接在方法中用this,就能夠獲取到被裝飾的對(duì)象躁倒。

通過this獲取到被裝飾的對(duì)象

鏈?zhǔn)秸{(diào)用需要是倒著讀的,從后往前讀如下洒琢。排序器首先調(diào)用apply方法獲取sortedBy值秧秉,并把sortedBy為null的元素都放到最前面,然后把剩下的元素按sortedBy進(jìn)行自然排序衰抑。

Ordering ordering = Ordering.natural().nullsFirst().onResultOf(function)象迎;

類似的用Apache工具類實(shí)現(xiàn)則為

Comparator.nullHighComparator((Comparator.transformedComparator(ComparatorUtils.naturalComparator(),funtion));

三、Java原生的Comparator構(gòu)造方法

? ? 雖然Java原生的Comparator構(gòu)造方法不如前兩者簡單易用呛踊,但其實(shí)Comparator類中也提供了一些比較簡單的構(gòu)造Comparator的方法砾淌,而不需要在public int compare(To1,To2)方法里面用一長串多層If嵌套的代碼來編寫排序規(guī)則。

Comparator很類似于Ordering恋技,Comparator類也提供了基礎(chǔ)的自然排序拇舀。

public static?Comparator naturalOrder();

public static?Comparator reverseOrder()蜻底; //自然排序倒序

null值在前面排序

public static Comparator nullsFirst(Comparator comparator)骄崩;

null值在后面排序

public static Comparator nullsLast(Comparator comparator);

對(duì)比較對(duì)象做處理薄辅,按Function 返回值進(jìn)行排序要拂;

public static Comparator comparing(Function keyExtractor,Comparator keyComparator);

多規(guī)則排序(第一排序站楚、第二排序......);

Comparator thenComparing(Comparator other)脱惰;

? ? 可以看到Ordering和原生的Java Comparator構(gòu)造方法有很多相似之處,相比之下窿春,Comparator只不過是沒Ordering功能那么強(qiáng)大拉一,但也不算很糟糕。

下面通過一個(gè)例子來展示上面三種構(gòu)造方法的區(qū)別旧乞。

? ? 一個(gè)User類蔚润,里面有id,firstName尺栖,lastName嫡纠,age字段,現(xiàn)在按照優(yōu)先級(jí)為age升序、firstName升序除盏、lastName倒序進(jìn)行排序叉橱,代碼如下。

User類
三種不同的排序代碼
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末者蠕,一起剝皮案震驚了整個(gè)濱河市窃祝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌踱侣,老刑警劉巖锌杀,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異泻仙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)量没,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門玉转,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人殴蹄,你說我怎么就攤上這事究抓。” “怎么了袭灯?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵刺下,是天一觀的道長。 經(jīng)常有香客問我稽荧,道長橘茉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任姨丈,我火速辦了婚禮畅卓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蟋恬。我一直安慰自己翁潘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布歼争。 她就那樣靜靜地躺著拜马,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沐绒。 梳的紋絲不亂的頭發(fā)上俩莽,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音洒沦,去河邊找鬼豹绪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瞒津。 我是一名探鬼主播蝉衣,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼巷蚪!你這毒婦竟也來了病毡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤屁柏,失蹤者是張志新(化名)和其女友劉穎啦膜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淌喻,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡僧家,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裸删。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片八拱。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖涯塔,靈堂內(nèi)的尸體忽然破棺而出肌稻,到底是詐尸還是另有隱情,我是刑警寧澤匕荸,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布爹谭,位于F島的核電站,受9級(jí)特大地震影響榛搔,放射性物質(zhì)發(fā)生泄漏诺凡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一药薯、第九天 我趴在偏房一處隱蔽的房頂上張望绑洛。 院中可真熱鬧,春花似錦童本、人聲如沸真屯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绑蔫。三九已至,卻和暖如春泵额,著一層夾襖步出監(jiān)牢的瞬間配深,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工嫁盲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篓叶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像缸托,于是被迫代替她去往敵國和親左敌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法俐镐,類相關(guān)的語法矫限,內(nèi)部類的語法,繼承相關(guān)的語法佩抹,異常的語法叼风,線程的語...
    子非魚_t_閱讀 31,631評(píng)論 18 399
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司棍苹,掛了不少无宿,但最終還是拿到小米、百度枢里、阿里懈贺、京東、新浪坡垫、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,246評(píng)論 11 349
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對(duì)于byte類型而言...
    龍貓小爺閱讀 4,261評(píng)論 0 16
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理配乱,服務(wù)發(fā)現(xiàn)溉卓,斷路器,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 汽車工程專業(yè)相關(guān)的研究都可以有如下套路: 1)物理對(duì)象(電池搬泥、燃料電池桑寨、發(fā)動(dòng)機(jī)、電機(jī))數(shù)學(xué)描述(運(yùn)動(dòng)忿檩、反應(yīng)) 2)...
    onebean閱讀 373評(píng)論 0 2