繁体   English   中英

Java Collectors.groupingBy()---是否有List命令?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM