Java groupingBy收集器是否保留列表顺序?

Java groupingBy收集器是否保留列表顺序?,java,java-stream,collectors,Java,Java Stream,Collectors,考虑一个列表list,其中元素按People.getAge()的升序排序。如果我们使用Collectors.groupingBy(People::getCity)对该列表进行分组,那么每个组/城市的结果列表是否仍按年龄排序 在实践中,它似乎确实维护了秩序。我在找担保书 该方法的Javadoc说明: 如果不需要保留元素在结果映射收集器中的显示顺序,则使用groupingByConcurrent(函数)可以提供更好的并行性能 我不确定这是否是指清单上项目的顺序 理解合同的关键在于合同中的“元素出现的

考虑一个列表
list
,其中元素按
People.getAge()
的升序排序。如果我们使用Collectors.groupingBy(People::getCity)对该列表进行分组,那么每个组/城市的结果列表是否仍按年龄排序

在实践中,它似乎确实维护了秩序。我在找担保书

该方法的Javadoc说明:

如果不需要保留元素在结果映射收集器中的显示顺序,则使用groupingByConcurrent(函数)可以提供更好的并行性能


我不确定这是否是指清单上项目的顺序

理解合同的关键在于合同中的“元素出现的顺序”。它讨论它们是否按顺序到达,这意味着它们是否按顺序传递给键提取器
函数
和任何下游收集器;它没有说明在任何结果积累中是否会保留秩序;实际上,
groupingBy
的当前实现使用了一个不保留键顺序的
HashMap

您询问它是否指列表中项目的顺序。如果您引用的是创建流所依据的列表,则在列表上创建的流一开始是有序的,但某些流操作会更改顺序或使其无序,因此,如果流保持有序,则它引用的顺序是指管道操作完成后的结果顺序。如果流操作使流无序,则元素在收集器中的显示顺序不再是问题


如果您指的是列表中项目的顺序,则分组项目的收集顺序是,因为“元素出现的顺序”是处理元素的顺序。当分组到下游收集器时,同样适用;如果流仍然是有序的,并且您分组到一个保留顺序的下游收集器,这将保留该顺序,而并发版本可能不会。

您的Javadoc报价非常明显地说明了这一点。你为什么有疑问?@FrankPuffer:地图收集器,它指的是用来构建地图元素的toList收集器吗?@FrankPuffer:没错,上面的引文表明,
groupingBy
保留了顺序,但遗憾的是,没有说要这样做。这很糟糕,因为虽然我们可以查看OpenJDK实现或进行实证测试,但它们告诉我们的只是实现当前的功能,而不是契约。所以,希望JDKAPI文档中的某个地方能对此进行澄清。@FrankPuffer引用的部分实际上没有。只谈不需要保全的情况,不谈需要保全的情况;)@T.J.Crowder,@Mifeet:从严格的逻辑观点来看,你是对的。但是如果
groupingBy
不能保证秩序的维护,那么引用的句子就没有意义了。(我不希望在标准包的JavaDoc中出现无意义的语句。)引用的JavaDoc是“如果保留元素在结果映射中出现的顺序…”。确切地说,它只说结果中的顺序是保留的,因此可以解释为:给定相同的输入,无论您处理它多少次,结果顺序都是相同的。因此,即使传入流中的顺序没有被保留,只要结果是一致的,它仍然满足Javadoc所说的。(我也相信Javadoc的初衷是说,与输入相对应的顺序是保留的。然而,它是用含糊不清的文字写成的)虽然在技术上不明确,但在本文中,“保留顺序”可能指的是在输出中保留输入顺序。“保持秩序”是一个常用的短语,用来描述这个确切的事情。