回想一下,排序表是以 List 對象的形式作為一個 Map 中的值而被存儲的。修改后的打印代碼通過 Map 的 values視圖進行迭代, 將每一個通過最小尺寸測試的List放進List 之中。然后,代碼使用一個期望 List 對象的 Comparator 為這個 List 排序,并實現反轉大小排序。最終,代碼通過現在已排序的 List 進行迭代,打印它的元素(排序組)。這個代碼在 Perm 的 main 方法末尾替代了打印代碼:
// Make a List of all permutation groups above size threshold
List winners = new ArrayList();
for (Iterator i = m.values().iterator(); i.hasNext(); ) {
List l = (List) i.next();
if (l.size() = minGroupSize)
winners.add(l);
}
// Sort permutation groups according to size
Collections.sort(winners, new Comparator() {
public int compare(Object o1, Object o2) {
return ((List)o2).size() - ((List)o1).size();
}
});
// Print permutation groups
for (Iterator i=winners.iterator(); i.hasNext(); ) {
混排算法所做的正好與 sort 相反: 它打亂在一個 List 中可能有的任何排列的蹤跡。也就是說,基于隨機源的輸入重排該 List, 這樣的排列具有相同的可能性(假設隨機源是公正的)。這個算法在實現一個碰運氣的游戲中是非常有用的。例如,它可被用來混排代表一副牌的 Card 對象的一個 List 。另外,在生成測試案例時,它也是十分有用的。
這個操作有兩種形式。第一種只采用一個 List 并使用默認隨機源。第二種要求調用者提供一個 Random 對象作為隨機源。這個算法的一些實際代碼曾在 List 課程中被作為例子使用。
常規數據操作(Routine Data Manipulation)
Collections 類為在 List 對象上的常規數據操作提供了三種算法。這些算法是十分簡單明了的:
reverse: 反轉在一個列表中的元素的順序。
fill: 用特定值覆蓋在一個 List 中的每一個元素。這個操作對初始化一個 List 是十分有用的。
copy: 用兩個參數,一個目標 List 和一個源 List, 將源的元素拷貝到目標,并覆蓋它的內容。目標 List 至少與源一樣長。假如它更長,則在目標 List 中的剩余元素不受影響。
搜索(Searching)
binary search (二進制搜索)算法用二進制搜索算法在一個已排序的 List 中尋找特定元素。這個算法有兩種形式。第一種采用一個 List 和一個要尋找的元素 ( "搜索鍵(search key)")。這種形式假設 List 是按照它的元素的自然排序排列成上升順序的。第二種形式除采用 List 外,還采用一個 Comparator 以及搜索鍵,并假設 List 是按照特定 Comparator 排列成上升順序的。 排序算法(描述見上) 可優先于 binarySearch 而被用來為List 排序。
兩種形式的返回值是相同的: 假如 List 包含搜索鍵,它的索引將被返回;假如不包括,則返回值為 (-(insertion point) - 1), 這里的 insertion point 被定義為一個點,從這個點該值將被插入到這個 List 中:大于該值的第一個元素的位置索引,或list.size()。 選用這個不可否認的難看的公式是為了保證假如且僅假如搜索鍵被發現,則返回值將等于0。它基本上是一個將布爾邏輯 ("found") 和整數 ("index") 綜合到單一的int返回值的大雜燴。