iterable.forEach()和iterable.stream().forEach()的区别

8

看起来我可以直接在我的集合上调用 list.forEach(a -> a.stuff()),而不是 list.stream().forEach(a -> a.stuff())。除了使用 parallelStream() 之外,我应该在什么情况下使用其中之一?

1个回答

15

有一些不同之处:

Iterable.forEach 保证按迭代顺序处理,如果定义了 Iterable。(对于列表,迭代顺序通常是明确定义的。) Stream.forEach 不行;必须使用 Stream.forEachOrdered 代替。

Iterable.forEach 可能允许在底层数据结构上产生副作用。虽然许多集合的迭代器在迭代期间修改集合会抛出ConcurrentModificationException,但某些集合的迭代器明确允许它。例如,请参阅 CopyOnWriteArrayList。相比之下,流操作通常不能干扰流源。

如果 Iterable 是同步包装集合,例如来自 Collections.synchronizedList(),对其调用 forEach 将在整个迭代期间保持其锁定。这将防止其他线程在迭代期间修改集合,确保迭代看到集合的一致视图,并防止 ConcurrentModificationException。这也将防止其他线程在迭代期间读取集合。但是,这不适用于流。没有什么可以防止集合在流操作期间被修改,如果发生修改,则结果是未定义的。


“防止其他线程修改它” - 或者从中读取,当然?你最后的观点似乎暗示Stream.forEachIterable.forEach相比允许修改流源。我怀疑你是否想这样暗示! - Maurice Naftalin
我肯定不是想暗示那个意思!我想我应该澄清一下最后一点。 - Stuart Marks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接