Collectors.groupingBy分組後的排序問題
默認groupingBy代碼裏會生成一個HashMap(hashMap是無序的,put的順序與get的順序不一致)
- HashMap是無序的,HashMap在put的時候是根據key的hashcode進行hash然後放入對應的地方。所以在按照一定順序put進HashMap中,然後遍歷出HashMap的順序跟put的順序不同(除非在put的時候key已經按照hashcode排序號了,這種幾率非常小)
- 單純的HashMap是無法實現排序的,這的排序是指,我們將鍵值對按照一定的順序put進HashMap裏,然後在進行取鍵值對的操作的時候,是按照put進去的順序把鍵值對取出來的。
- JAVA在JDK1.4以後提供了LinkedHashMap來幫助我們實現了有序的HashMap!LinkedHashMap取鍵值對時,是按照你放入的順序來取的。
這就造成了一個List<Model>如果是有序的,在 groupingBy後 model的順序是不可控的.
現在遇到這樣一個場景
在CMS裏,每個頁面的模塊是按順序排放的,每個模塊的內容也是按順序的如
List<Model> list=Arrays.asList(m1,m2,m3)
現在需要對裏面的元素分組,但是分組後的順序也必須是 m1,m2,m3...中間可以缺少,但是不能亂序
以下是合法的 m1,m3 或者 m2,m3 但是不能 m3,m2
如以下代碼 list的順序是 id=2的在 id=1之前, 分組之後的訪問也必須是id=2的在前才對
但是如果調用 默認的分組,就會發現 id=1的在前了 (在後的將要在前;在前的將要在後了)
輸出總是
1
[A12,A11]
2
[A2,A21]
但是期望輸出為
2 [A21,A2] 1 [A12,A11]
如果需要保持排序就不能使用默認的 方法了,必須使用 被註釋的方法 (明確使用LinkedHashMap來保持順序).
下面是groupingBy的參數說明
可以看到有三個參數,第一個參數就是key的Function
了,第二個參數是一個map工廠,也就是最終結果的容器,一般默認的是采用的HashMap::new
,最後一個參數很重要是一個downstream
,類型是Collector
-
第一個參數:分組按照什麽分類
-
第二個參數:分組最後用什麽容器保存返回
-
第三個參數:按照第一個參數分類後,對應的分類的結果如何收集
其實一個參數的Collectors.groupingBy
方法的 ,第二個參數默認是HashMap::new
, 第三個參數收集器其實默認是Collectors.toList
Collectors.groupingBy分組後的排序問題