灵感来自这个问题 https://stackoverflow.com/questions/44944973/search-for-example-of-inconsistent-behavior-java-8-stream,我开始研究有序流与无序流、并行流与顺序流以及尊重顺序的终端操作与不尊重顺序的终端操作。
在链接问题的一个答案中,显示了与此类似的代码:
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
list 甚至从一次运行到另一次运行都会发生变化,表明结果实际上是不确定的。
所以我创建了另一个例子:
CopyOnWriteArrayList<Integer> result2 = ordered.parallelStream()
.unordered()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
System.out.println(ordered);
System.out.println(result2);
我预计会看到类似的结果,因为流既是并行的又是无序的(也许unordered()
是多余的,因为它已经是并行的)。但是,结果列表是有序的,即它等于源列表。
所以我的问题是为什么收集的列表是有序的?做collect
始终尊重遭遇顺序,即使对于并行、无序的流也是如此?是具体的吗Collectors.toCollection(...)
收集者是强制遭遇秩序的那个吗?