【发布时间】:2017-12-10 18:53:36
【问题描述】:
受this question 的启发,我开始研究有序流与无序流、并行流与顺序流以及尊重顺序的终端操作与不尊重顺序的终端操作。
在链接问题的一个答案中,显示了与此类似的代码:
List<Integer> ordered = Arrays.asList(
1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4);
List<Integer> result = new CopyOnWriteArrayList<>();
ordered.parallelStream().forEach(result::add);
System.out.println(ordered);
System.out.println(result);
而且列表确实不同。 unordered 列表甚至会从一个运行变为另一个,表明结果实际上是不确定的。
所以我创建了另一个示例:
CopyOnWriteArrayList<Integer> result2 = ordered.parallelStream()
.unordered()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
System.out.println(ordered);
System.out.println(result2);
我希望看到类似的结果,因为流既是并行的又是无序的(也许unordered() 是多余的,因为它已经是并行的了)。但是,结果列表是有序的,即它等于源列表。
所以我的问题是为什么收集的列表是有序的? collect 是否总是尊重遭遇顺序,即使是并行的、无序的流?是特定的Collectors.toCollection(...) 收集器强制遇到顺序吗?
【问题讨论】:
-
非常有趣的问题,但最后一个是题外话。你最好把它从你的帖子中删除。
-
是的,这样会更好。
-
顺便说一句,它正在慢慢成为流的 SO 标准;这是 Holger 的必读内容:stackoverflow.com/questions/41894173/…
-
unordered()是 not 冗余的,因为并行并不意味着无序。这已经解释了here。说无序终端操作“不尊重”遭遇顺序是错误的。它的无序特性意味着顺序对结果没有意义,例如在对整数求和或收集到HashSet时。当您明确地说unordered()时,您也是在说顺序无关紧要,即使您可以识别结果列表中的顺序。如果订单与您无关,那毫无疑问……
标签: java java-8 java-stream