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

Java流与迭代器

法景明
2023-03-14

我一直在玩Java新的和闪亮的功能部分,最让我困惑的事情之一是流?

它们有什么用?

在谷歌上,我主要找到了如何使用它们的解释和实际例子,我已经记下来了,没有关于幕后魔法的具体内容,这是我感兴趣的。

我的意思并不是说,从实际意义上讲,我从一些函数语言中找到了map/filter/reduce/etc。相当快,但为什么我们需要先转换为流?Java已经有了迭代器。流和迭代器之间是否有根本的区别,比如一个是懒惰的,另一个不是?还是别的什么?

底线:迭代器和流之间的根本区别是什么?哪些功能不能作为迭代器的扩展来实现,需要一个全新的类型家族?

共有3个答案

林波鸿
2023-03-14

流和迭代器之间有根本的区别吗,比如一个懒惰,另一个不懒惰?还是别的什么?

是的,根本的区别是流是在内部处理的。当我们运行一个流时,我们说的是,我们想要所有这些东西,在这个条件下,过滤到这些东西中,并给我们这个结果。我们不会理所当然地说任何关于我们希望如何发生的事情。这意味着相同的源代码可以在图形卡上并行运行,或者以任何未知的方式运行。我们只是希望这一切发生。

作为程序员,如果我们明确自己不关心的标准,那么在幕后会发生很多有趣的事情。这也是函数接口和一些lambda表达式背后的魅力所在。这个想法是,如果我们说我们最初不关心,那么编译器可以以任何方式解决它,而不是程序说如何解决它。有时,不同的计算机配置可以以不同的方式更好地解决问题,例如更好的并行化。

底线:迭代器和流之间的根本区别是什么?哪些功能不能作为迭代器的扩展来实现,需要一个全新的类型家族?

迭代器说需要如何解决这个问题。它需要执行这个元素,然后是这个元素,然后是这个元素,编译器无法知道是否有一些深层且看似隐藏的原因,而不是其他方式。流说你不在乎,在一千个不同的处理器上向后迭代,在GPU上,没关系。

我希望每个元素都以这种方式处理。我希望一个接一个的元素以这种方式处理。后者实际上是不必要的限制。

经俊茂
2023-03-14

将< code>Stream的方法添加到现有的< code>Iterator中绝对是可能的,因为可以为所有附加的方法提供默认的实现,但是这种API更改带来了明显的缺点:

  • 您的流与迭代器“结婚”,即使在您不想要迭代器的情况下(例如生成器流)
  • 您不会“免费”从集合中获取流-就像您调用stream一样,您需要调用迭代器(使用迭代器的增强循环已经是这种情况)
  • 您仍然需要为原始流提供大量新类型,因为迭代器中没有类似的概念。这是很难“移植”到迭代器上的功能。

将流与迭代器合并的总体收益看起来并不多,因此看起来API设计者采用了一种干净的方法。

公羊曜灿
2023-03-14

一般来说,谈论流是一个很大的话题。但是,我将得出为什么您应该偏爱流API而不是迭代器。

首先,使用流API,我们现在可以在更高的抽象级别上进行编程,就像SQL查询一样,即我们表达我们想要的内容并让库处理其余部分。

第二,流操作在幕后执行其迭代(内部迭代),这意味着数据处理可以并行进行,或者以不同的顺序进行,可以更优化。

另一方面,如果您决定显式迭代集合以执行一些计算,无论是使用迭代器还是迭代器的语法糖(增强的for循环),那么您就是显式获取集合中的项目并逐个处理它们,因此它本质上是串行的。

使用迭代器而不是流API也意味着当您想要并行或找到优化程序的不同方法时,需要做更多的工作。

然而,这也意味着您将花费更多时间处理低级细节,而不仅仅是关注您希望您的程序做什么。

在Java-8 in Action一书中还提到:

Streams库中的内部迭代可以自动选择并行性的数据表示和实现来匹配您的硬件。相比之下,一旦您通过编写for-each选择了外部迭代,那么您基本上就致力于自我管理任何并行性。(实际上,自我管理意味着“总有一天我们会并行化它”或“开始涉及任务和同步的漫长而艰巨的战斗”。)

Java8需要一个类似集合但没有迭代器的接口,即ergo流!

本质上,使用流API,您的生活在许多方面都要容易得多,但我发现最有用的是,您现在可以投入更多时间专注于您希望代码做什么,同时您可以决定去并行而不处理低级的东西。

当然,这并不是说要始终尽可能使用流。相反,它说明了使用流而不是迭代器的好处。

在某些地方,使用迭代器比使用流API更合适,反之亦然。因此,在处理集合中的数据时,要明智地选择使用哪种方法

 类似资料:
  • 问题内容: 为了利用Jdk 8中包含的多种查询方法,我尝试设计一种域模型,其中具有多重性(具有零个或多个实例)的关系的获取器返回a 而不是or 。 我的疑问是,与相比,是否还会产生任何额外的管理费用? 那么,用损害我的域模型是否有任何缺点? 或者,我是否应该始终返回或,并通过将迭代器与转换为最终结果,让最终用户选择是否使用流的决定? 请注意 ,返回a 是无效的选项,因为在这种情况下,大多数关系都是

  • 为了利用Jdk 8的中包含的各种查询方法,我试图设计域模型,其中与多重性(具有零个或多个实例)关系的获取器返回

  • 问题内容: 在一次采访中有人问我,使用迭代器使用for循环有什么好处,或者使用循环比迭代器有什么好处? 任何人都可以回答这个问题,以便将来如果我遇到类似的问题,那么我可以回答 问题答案: 首先,有两种for循环,它们的行为非常不同。一种使用索引: 这种循环并非总是可能的。例如,列表具有索引,而集合没有索引,因为它们是无序集合。 另一个foreach循环在幕后使用Iterator: 这适用于每种It

  • 本文向大家介绍Python迭代器与可迭代与生成器,包括了Python迭代器与可迭代与生成器的使用技巧和注意事项,需要的朋友参考一下 示例 一个迭代是一个对象,可以返回一个迭代器。具有状态且具有__iter__  方法并返回迭代器的任何对象都是可迭代的。也可能是没有状态的对象,该对象实现了__getitem__方法。-该方法可以获取索引(从零开始),并IndexError在索引不再有效时引发。 Py

  • 我有一个顺序数据源,表示为简单迭代器(或流)。数据相当大,不适合内存。此外,源代码可以遍历一次,并且获取成本很高。该源用于一些重过程(黑盒),该过程将迭代器(或流)作为其参数来使用线性数据。好的,很简单。但如果我有两种不同的消费程序,我该怎么办??正如我所说的,我不想将输入数据吸入类似列表的集合中。我也可以从一开始就重读源代码两次来完成我的任务,但我不喜欢这样,因为这样做没有效果。如果事实上我需要

  • 我想在字符串与给定值匹配时更新该值 有没有人可以使用Java streams API来实现上述功能