Rar*_*ima 9 java iterator java-8 java-stream
我一直在玩Java中新的和闪亮的功能部分,其中一个让我最困惑的事情是流?
它们的用途是什么?
在谷歌上,我主要找到了如何使用它们的解释和实际例子,我已经说过,没有具体的幕后魔术,这是我感兴趣的.
我不是指在实际意义上,来自一些函数式语言我想出了map/filter/reduce/etc. 相当快,但为什么我们需要先转换为流?Java已经有了迭代器.流和迭代器之间是否存在根本区别,例如一个是懒惰而另一个不是?或者是别的什么?
底线:迭代器和流之间的根本区别是什么,哪些功能无法实现为迭代器的扩展,需要一个全新的类型系列?
Ous*_* D. 11
一般来说,谈论流是一个很大的话题.但是,我将推导出为什么你应该优先于Iterators上的流API.
首先,使用流API,我们现在可以在更高的抽象级别进行编程,就像SQL查询一样,即我们表达我们想要的东西,并让库处理其余的.
其次,流操作在幕后执行它们的迭代(内部迭代),这意味着数据的处理可以并行地或以可以更优化的不同顺序完成.
另一方面,如果您决定显式迭代您的集合以执行某些计算,无论是迭代器还是迭代器的语法糖(增强的for循环),那么您将明确地获取集合中的项并处理它们一个接一个,因此它本身就是连续的.
使用迭代器而不是流API也意味着当你想要并行或找到不同的方法来优化你的程序时,还有很多工作要做.
然而,这也意味着您花费更多时间处理低级细节,而不是只关注您希望程序执行的操作.
Java-8 in Action书中也提到了:
Streams库中的内部迭代可以自动选择数据表示和并行实现以匹配您的硬件.相比之下,一旦你通过编写for-each选择了外部迭代,那么你基本上就致力于自我管理任何并行性.(在实践中自我管理意味着"一个好的日子,我们将并行化这个"或"开始涉及任务和同步的漫长而艰苦的战斗".)
Java 8需要像Collection这样的接口但没有迭代器,ergo Stream!
从本质上讲,使用流API,您的生活在很多方面都要容易得多,但我发现最有用的事实是您现在可以花更多的时间专注于您希望代码执行的操作,同时您可以决定平行而不处理低级别的东西.
这当然不是说总是在任何可能的地方使用流.相反,它说明了使用流而不是迭代器的好处.
在某些地方,使用迭代器而不是流API更合适,反之亦然.因此,明智地选择在处理集合中的数据方面继续采用哪种方法.
向Stream现有方法添加方法Iterator肯定是可能的,因为可以为所有其他方法提供默认实现,但是这种API更改带来了显着的缺点:
stream你需要调用的方式相同iterator(使用迭代器的增强循环就是这种情况)使用迭代器合并流的总体收益看起来并不多,所以看起来API设计师采用了干净的工作表方法.
流和迭代器之间是否存在根本区别,例如一个是懒惰的,另一个不是?或者是别的什么?
是的,根本的区别在于流是在内部处理的。当我们运行一个流时,我们所说的是我们想要所有这些东西,根据这个条件过滤这些东西,并给我们这个结果。当然,我们不会说出我们希望如何实现这一点。这意味着稍后可以在显卡上或以任何未知的方式并行运行相同的源代码。我们只是希望这件事发生。
如果我们作为程序员明确我们不关心的标准,那么幕后可能会发生很多有趣的事情。这也是函数式接口和一些 lambda 表达式背后的魅力所在。这个想法是,如果我们说我们最初不关心,那么编译器可以以解决它的任何方式来解决这个问题,而不是程序所说的解决它的方式。有时,不同的计算机安排可以以不同的方式更好地解决问题,例如更好的并行化。
底线:迭代器和流之间的根本区别是什么?哪些功能无法作为迭代器的扩展来实现,并且需要全新的类型系列?
迭代器表示问题需要如何解决。它需要执行这个元素,然后执行这个元素,然后执行这个元素,编译器无法知道是否有一些深层且看似隐藏的原因,而不是其他方式。Streams 说你不在乎,向前向后迭代,在一千个不同的处理器上,在 GPU 上,这并不重要。
我希望每个元素都以这种方式处理。我想要一个又一个元素以这种方式处理。后者实际上是不必要的限制。