[英]Java Collectors.groupingBy()---is List ordered?
對於返回Map<K,List<T>>
的Collectors.groupingBy()
Map<K,List<T>>
暗示List<T>
是為了評估流嗎?
我沒有看到列表排序的明確描述,而並發版本明確表示沒有排序。 如果它沒有以某種方式訂購,我會期望它是一個收藏品,我不會看到除了收到訂單之外的其他訂單。
我希望保證每個列表中的最后一個值是該組收到的最后一個值。
groupingBy()
的文檔說:
實施要求:
這會產生類似於的結果:
groupingBy(classifier, toList());
toList()
的文檔說:
返回:
Collector
,按照順序將所有輸入元素收集到List
中
因此,要回答您的問題,只要您的流具有已定義的遭遇訂單 ,您就可以獲得有序列表。
編輯:正如@Holger指出的那樣, groupingBy()
還必須遵守遭遇順序以保留toList()
的排序約束。 這一事實在本說明中強烈暗示:
實施說明:
...如果不需要保留向下游收集器提供元素的順序,則使用
groupingByConcurrent(Function, Collector)
可以提供更好的並行性能。
不幸的是,這種保證沒有明確說明。
但是,生成的Collector
當前沒有UNORDERED
特性,因此事實上,生成的List
是有序的。
剩下的問題是,因為沒有API合同不允許它,未來版本(或替代實現)是否可以添加該特性並生成無序列表? 實際上,OpenJDK和Oracle都非常不願意引入這些重大變化,即使它有充分的理由。
在這里,沒有理由做出這樣的改變; 我認為依靠這種行為是安全的。
我做了一個真正的測試,我用這個順序初始化一個ArrayList<TimeBased>
:
{"1", "2019-03-22 10:20:03", "1"},
{"2", "2019-03-22 10:30:03", "2"},
{"2", "2019-03-22 11:20:03", "3"},
{"1", "2019-03-22 11:20:15", "4"},
{"3", "2019-03-22 11:35:03", "5"},
{"2", "2019-03-22 12:20:03", "6"}
和分組通過第一和第二列,但結果是:
id birth number
1 Fri Mar 22 10:20:03 CST 2019 1
1 Fri Mar 22 11:20:15 CST 2019 4
2 Fri Mar 22 12:20:03 CST 2019 6
2 Fri Mar 22 11:20:03 CST 2019 3
2 Fri Mar 22 10:30:03 CST 2019 2
3 Fri Mar 22 11:35:03 CST 2019 5
所以你看,訂單是意外的(日期列順序混亂)。
在我這樣做之后(添加LinkedList :: new):
Map<Integer, Map<Date, List<TimeBased>>> grouped =
timeBasedBeans.stream().collect(groupingBy(TimeBased::getId, groupingBy(TimeBased::getPeriod,
LinkedHashMap::new, toList())));
那順序是對的:
id birth number
1 Fri Mar 22 10:20:03 CST 2019 1
1 Fri Mar 22 11:20:15 CST 2019 4
2 Fri Mar 22 10:30:03 CST 2019 2
2 Fri Mar 22 11:20:03 CST 2019 3
2 Fri Mar 22 12:20:03 CST 2019 6
3 Fri Mar 22 11:35:03 CST 2019 5
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.