Java Collectors.groupingBy()---is List order?

2022-09-01 18:59:54

对于返回是否意味着 is 是按照计算流的顺序?Collectors.groupingBy()Map<K,List<T>>List<T>

我没有看到对列表排序的明确描述,而并发版本明确声明没有排序。如果它没有以某种方式订购,我会期望它是一个集合,除了收到的订单之外,我看不出它可能是什么其他排序。

我希望可以保证每个列表中的最后一个值是该组收到的最后一个值。


答案 1

分组By()的文档说:

实施要求:

这将生成类似于以下内容的结果:

groupingBy(classifier, toList());

toList() 的文档说:

返回:

a 它按遇到顺序将所有输入元素收集到一个CollectorList

因此,为了回答您的问题,只要您的流具有定义的遭遇顺序,您就一定可以获得有序列表。


编辑:正如@Holger所指出的,还必须尊重遭遇顺序,以保持 的排序约束。它这样做的事实在本说明中强烈暗示:groupingBy()toList()

实施说明:

...如果不需要保留元素呈现给下游收集器的顺序,则使用可以提供更好的并行性能。groupingByConcurrent(Function, Collector)


答案 2

我做了一个真正的测试,我用这个顺序初始化一个: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

推荐