当前位置: 首页 > 知识库问答 >
问题:

Collection.Stream().Foreach()和Collection.Foreach()之间有什么区别?

万高畅
2023-03-14

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

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

共有1个答案

邓元白
2023-03-14

对于如图所示的简单情况,它们基本上是相同的。然而,有一些细微的差别可能是重要的。

一个问题是订购。对于stream.foreach,顺序是未定义的。在顺序流中不太可能出现这种情况,但在stream.foreach的规范中,它可以以任意顺序执行。这种情况在并行流中确实经常发生。相反,iterable.foreach总是按照iterable的迭代顺序执行(如果指定了一个)。

另一个问题是副作用。stream.foreach中指定的操作必须是非干扰的。(请参阅java.util.Stream包文档)iterable.foreach的限制可能更少。对于java.util中的集合,iterable.foreach通常会使用该集合的iterator,其中大多数都设计成failfast,并且如果在迭代期间对集合进行结构修改,则会抛出ConcurrentModificationException。但是,在迭代过程中允许进行非结构化的修改。例如,ArrayList类文档说“仅仅设置元素的值并不是结构修改。”因此,允许ArrayList.foreach的操作在基础ArrayList中设置值而不会出现问题。

并发集合也是不同的。它们不是fail-fast,而是被设计成弱一致性。完整的定义在这一环节。不过,简而言之,考虑一下concurrentlinkeddeque。允许传递给其foreach方法的操作修改基础deque,即使是在结构上,也不会引发ConcurrentModificationException。但是,所发生的修改在此迭代中可能是可见的,也可能是不可见的。(因此存在“弱”一致性。)

如果iterable.foreach是在同步集合上迭代,则另一个区别是可见的。在这样的集合上,iterable.foreach获取集合的锁一次,并在对action方法的所有调用中保持它。stream.foreach调用使用集合的spliterator,该spliterator不锁定,并且依赖于不干涉的通行规则。支持流的集合可能在迭代期间被修改,如果是的话,可能会导致ConcurrentModificationException或不一致的行为。

 类似资料:
  • 问题内容: 我了解使用,我可以使用类似链操作或使用并行流。但是,如果我需要执行小的操作(例如,打印列表的元素),它们之间有什么区别? 问题答案: 对于诸如所示的简单情况,它们基本上是相同的。但是,有许多细微的差异可能很重要。 一个问题是订购。使用,顺序不确定。顺序流不太可能发生,但仍可以按任意顺序执行。这确实在并行流中经常发生。相反,如果指定,则总是以的迭代顺序执行。 另一个问题是副作用。必须指定

  • 这是一个例子:代码A: 另一个代码B可以这样使用: 两者有什么区别,有和没有?

  • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型

  • 问题内容: 今天,我按照一些说明在Linux中安装软件。有一个脚本需要首先运行。它设置一些环境变量。 指令告诉我要执行,但是我执行错误了。因此未设置环境。最后,我注意到了这一点并继续进行。 我想知道这两种调用脚本方法的区别。我对Linux完全陌生,所以请尽可能详细。 问题答案: 运行脚本,将启动一个新的运行脚本的外壳。新的外壳程序不会影响启动脚本的父外壳程序。 是的简写形式,它将在当前shell中

  • 问题内容: 我刚开始使用Spring。我遇到了很多教程。我看到使用更多的例子比。我查看了Spring文档,但无法弄清楚使用其中一个的好处。有人可以提供一些解释吗? 问题答案: 是的便捷子类。 JavaDoc描述了一些添加的属性,这些属性在某些情况下可能有用: UrlBasedViewResolver的便利子类,它支持InternalResourceView(即Servlet和JSP)以及诸如Jst

  • 问题内容: 我刚刚看到了包含标签的CSS代码。我看着MDN看看是什么,但我真的不明白。 有人可以解释它是如何工作的吗? 它会在我们通过CSS选择之前创建DOM元素吗? 问题答案: 根据这些文档,它们是等效的: 唯一的区别是CSS3中使用了双冒号,而单冒号是旧版本。 推理: CSS 3中引入了:: before表示法,以便在伪类和伪元素之间建立区别。浏览器还接受:在CSS 2中引入的表示法。