看起来我可以直接在我的收藏集上调用list.forEach(a -> a.stuff())
,而不是list.stream().forEach(a -> a.stuff())
。我什么时候才能使用另一个(parallelStream()
一边...)?
答案 0 :(得分:15)
存在一些差异:
Iterable.forEach
保证以迭代顺序处理,如果它是为Iterable定义的。 (对于列表,迭代顺序通常是明确定义的。)Stream.forEach
没有;必须使用Stream.forEachOrdered
代替。
Iterable.forEach
可能会对基础数据结构产生副作用。虽然很多收藏'如果在迭代期间修改了集合,迭代器将抛出ConcurrentModificationException
,一些集合'迭代器明确允许它。例如,请参阅CopyOnWriteArrayList
。相比之下,流操作通常不得干扰流源。
如果Iterable是一个同步的包装器集合,例如,来自Collections.synchronizedList()
,则对它的forEach
的调用将在整个迭代期间保持锁定状态。这将阻止其他线程在迭代期间修改集合,从而确保迭代看到集合的一致视图,并阻止ConcurrentModificationException
。 (这也会阻止其他线程在迭代期间读取集合。)这不是流的情况。没有什么可以阻止在流操作期间修改集合,如果确实发生了修改,结果是不确定的。