Fed*_*ner 8 java java-8 java-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);
Run Code Online (Sandbox Code Playgroud)
这些名单确实不同.该unordered列表甚至从一次运行变为另一次运行,表明结果实际上是非确定性的.
所以我创建了另一个例子:
CopyOnWriteArrayList<Integer> result2 = ordered.parallelStream()
.unordered()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
System.out.println(ordered);
System.out.println(result2);
Run Code Online (Sandbox Code Playgroud)
我希望看到类似的结果,因为流是并行和无序的(可能unordered()是多余的,因为它已经是并行的).但是,生成的列表是有序的,即它等于源列表.
所以我的问题是为什么收集的清单是有序的?是否collect总是尊重遭遇顺序,即使对于并行,无序的流?它Collectors.toCollection(...)是强制遭遇秩序的特定收集者吗?
Collectors.toCollection返回Collector缺少Collector.Characteristics.UNORDERED特征的a.另一个指定的收集器Collector.Characteristics.UNORDERED可能表现不同.
这就是说:"无序"意味着没有保证,不能保证变化. 如果库发现最简单的方法是按顺序处理无序集合,则允许这样做,并且允许该行为在周二或者满月时将释放更改为释放.
(另请注意,Collectors.toCollection如果您要使用并行流,则不需要使用并发集合实现; toCollection(ArrayList::new)可以正常工作.这是因为收集器没有Collector.Characteristics.CONCURRENT特性,因此它使用适用于非集合的集合策略即使使用并行流也可以并发收集.)
如果你使用无序流但是收集器不是UNORDERED,反之亦然,我怀疑你从框架得到任何保证.如果有一个表,它会说:"在这里DRAGONS未定义的行为." 我也期望在这里对不同类型的链式操作存在一些差异,例如Eugene提及findFirst在这里变化,即使findFirst本质上是有序操作 - unordered().findFirst()变得相当于findAny().
因为Stream.collect,我认为目前的实施有三种策略:
| 归档时间: |
|
| 查看次数: |
128 次 |
| 最近记录: |