gpt4 book ai didi

java - Collection.stream().forEach() 和 Collection.forEach() 有什么区别?

转载 作者:bug小助手 更新时间:2023-10-28 10:39:32 24 4
gpt4 key购买 nike

我知道通过 .stream(),我可以使用 .filter() 之类的链式操作或使用并行流。但是如果我需要执行小操作(例如,打印列表的元素),它们之间有什么区别?

collection.stream().forEach(System.out::println);
collection.forEach(System.out::println);

最佳答案

对于如图所示的简单情况,它们大多相同。但是,存在许多可能很重要的细微差别。

一个问题是订购。使用 Stream.forEach,顺序是 undefined。顺序流不太可能发生这种情况,但它仍然在 Stream.forEach 以任意顺序执行的规范内。这在并行流中确实经常发生。相比之下,Iterable.forEach 总是按照 Iterable 的迭代顺序执行,如果指定了一个。

另一个问题是副作用。 Stream.forEach 中指定的操作必须是不干扰。 (参见 java.util.stream package doc。) Iterable.forEach 可能有更少的限制。对于java.util中的集合,Iterable.forEach一般会使用该集合的Iterator,大部分设计为fail-fast如果在迭代期间对集合进行了结构修改,则会抛出 ConcurrentModificationException。但是,在迭代期间允许进行非结构性修改。例如,ArrayList class documentation说“仅仅设置元素的值不是结构修改。”因此,ArrayList.forEach 的操作可以毫无问题地在底层 ArrayList 中设置值。

并发集合再次不同。它们不是快速失败,而是设计为 weakly consistent .完整的定义在那个链接上。不过,简而言之,考虑 ConcurrentLinkedDeque。传递给它的 forEach 方法的 Action is 允许修改底层双端队列,甚至在结构上,并且永远不会抛出 ConcurrentModificationException。但是,发生的修改可能在此迭代中可见,也可能不可见。 (因此“弱”一致性。)

如果 Iterable.forEach 正在对同步集合进行迭代,那么还有另一个区别是可见的。在这样的集合上,Iterable.forEach takes the collection's lock一次并将其保存在对操作方法的所有调用中。 Stream.forEach 调用使用集合的分离器,它不锁定,并且依赖于不干涉的普遍规则。支持流的集合可以在迭代期间被修改,如果是,则可能导致 ConcurrentModificationException 或不一致的行为。

关于java - Collection.stream().forEach() 和 Collection.forEach() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23218874/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com