[Guava源碼分析]Ordering:排序

個人技術博客常常被流氓網站惡意爬取轉載。請移步原文:http://www.cnblogs.com/hamhog/p/3876466.html,享受整齊的排版、有效的連接、正確的代碼縮進、更好的閱讀體驗。html

API

實例化

直接得到 natural() 天然序
usingToString() 字典序
指定 from(Comparator) 包裝Comparator
explicit(List) explicit(least, ... others) 指明這幾個東西的順序,只排它們
直接繼承  
其餘 allEqual() 全相等。(穩定排序中)保持原序,可用來把null置後等
arbitrary() 任意序,彷佛沒什麼意義。對VM週期是不變的。

繼承寫法:算法

 

Ordering<String> byLengthOrdering = new Ordering<String>() {
    public int compare(String left, String right) {
        return Ints.compare(left.length(), right.length());
    }
};

allEqual用法:app

Ordering.allEqual().nullsLast().asList(t, null, e, s, null, t, null)); 
//return [t, e, s, t, null, null, null]

修飾方法

鏈式調用

reverse()  
nullsFirst()  
nullsLast()  
onResultOf(Function) 先應用Function
lexicographical()  類「字典序」,對於Iterable一位一位比下去

 

BreakTie

compound(Comparator)
compound(Iterable comparators)

 

應用

min(a,b) min(a,b,c, ...rest) min(Iterator) min(Iterable)   另有max
leastOf(Iterable, int k) leastOf(Iterator, int k) 最小的k個元素 另有greatestOf
sortedCopy(Iterable) 返回排好的List 另有immutableSortedCopy
isOrdered(Iterable) 判斷是否是已經有序 另有isStrictlyOrdered

 

源碼分析

1. 排序是怎麼實現的?

natural

NaturalOrdering類
單例
compare() 直接調left.compareTo(right)
另見ReverseNaturalOrdering
以上兩類reverse()方法互相轉換。源碼分析

toString

UsingToStringOrdering類
單例
compare()二者的toString優化

use comparator

ComparatorOrdering類
持有一個Comparator實例
compare()調Comparator網站

explicit

ExplicitOrdering類
持有一個rankMap
compare()以rank排序spa

others

AllEqualOrdering類
單例
compare()返回0rest

ArbitraryOrdering內部類
單例
compare()先比較Java給出的hashCode,如衝突用computingMap遞增標記(1,2,3,4這樣標下去)code

2. 鏈式調用

典型的裝飾模式,如下每一個類都繼承自Ordering,同時持有一個Ordering實例(大魚吃小魚,小魚吃蝦米)htm

Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(sortKeyFunction)


先ByFunctionOrdering,調用sortKeyFunction.apply();而後NullsFirstOrdering,處理null;而後NaturalOrdering,調compareTo

ReverseOrdering類
compare()內層反向,逆轉min、max

NullsFirstOrdering類
compare()先處理null,非null再調內層
另見NullsLastOrdering

ByFunctionOrdering類
持有Function
compare()先調function.apply(),用返回值排

LexicographicalOrdering類
compare()一位一位比過去,直到決出勝負或有一邊斷了

特殊:

CompoundOrdering類
持有一個Comparator List
compare()用List裏的Comparator依次比較

不要把它跟別的鏈式調用寫在一塊兒。

3. 怎麼找出最大/小的k個元素?

用到一個特殊算法。但若是要找的元素個數超過總數一半,則不用算法,而是直接排序截取,這樣更快。算法適用於k遠小n的狀況。算法流程:保持一個2k大小的buffer;每次滿了時,清掉較大的一半,剩下k位。*剪枝優化:維護一個第k小的閾值,大於它的能夠直接忽略了*清掉一半的方法:快速選擇。定一個標誌位,比它小的挪到左邊,比它大的挪到右邊時間O(n + k log k) 存儲O(k)

相關文章
相關標籤/搜索