1. 程式人生 > >原始碼閱讀之Ordering

原始碼閱讀之Ordering

注重greatestOf 的演算法實現

舉個栗子:

List<Integer> listInt = Lists.newArrayList(4, 2, 0, 1, 3);
List<String> listString = Lists.newArrayList("abc", "bc", "ab", "ba");
Collections.sort(listInt, Ordering.natural().reverse());
log.info("按照自然序排序後反轉:{}", listInt.toString());
Collections.sort(listString, Ordering.natural());
log.info("字串按照自然序:{}", listString);
 
Collections.sort(listString, Ordering.usingToString());
log.info("通過呼叫其toString()返回的字串進行排序:{}", listString);
 
List<String> listTemp = Lists.newArrayList("abc", "bc", "ab", "ba", null);
Collections.sort(listTemp, Ordering.natural().nullsFirst()/*.nullsLast()*/);
log.info("使用當前排序器,但會把空值排在最前(後):{}", listTemp);
 
log.info("獲取最大的元素:{}", Ordering.natural().max(listInt)); //獲取最大的元素4 ,需要注意, max 和 min 都是按照當前list的前後為根據。list.get(0)就是最小元素
log.info("獲取最大的元素:{}", Ordering.natural().reverse().min(listInt));//獲取最小的元素4
log.info("獲取最大的元素:{}", Ordering.natural().reverse().max(listInt));//獲取最大的元素0
 
List<Integer> greatestKOfListIntList = Ordering.natural().greatestOf(listInt,3);//.leastOf(listInt,3);
//返回的list是不可變類,如果修改greatestKOfListIntList會拋異常
log.info("listInt最大的前{}個元素:{}",3,greatestKOfListIntList);
greatestOf 是 通過呼叫reserver().leastOf () 來實現。

而且對於k的值在大於 size/2 和 小於size/2 的時候,做了不同處理。

k < size/2 時,呼叫 Collections.sort;  k < size 時候,切割list返回,k > size 返回全部list

k > size/2  並且 k >= Integer.MAX_VALUE / 2,同上

k > size/2  並且 k < Integer.MAX_VALUE / 2,

/*維護一個大小為2*k的緩衝區。每一次緩衝區滿了,找到中間值並圍繞它進行分割槽,保持

*只有最低的k個元素。這需要n/k個查詢-中間和分割槽

*步驟,每一步都需要O(k)時間用傳統的快速選擇排序。

*/