Scala 流vs视图vs迭代器
scala中的流、视图(SeqView)和迭代器之间有什么区别?这是我的理解:Scala 流vs视图vs迭代器,scala,scala-collections,Scala,Scala Collections,scala中的流、视图(SeqView)和迭代器之间有什么区别?这是我的理解: 它们都是懒惰的列表 流缓存这些值 迭代器只能使用一次?您不能返回到开始并再次计算该值吗 视图的值不会被缓存,但您可以反复计算它们 因此,如果我想节省堆空间,我应该使用迭代器(如果我不再遍历列表)还是视图?谢谢 首先,它们都是不严格的。这对函数有特殊的数学意义,但基本上意味着它们是按需计算的,而不是预先计算的 Stream确实是一个惰性列表。事实上,在Scala中,流是一个列表,其尾部是一个惰性val。计算后,值保
- 它们都是懒惰的列表
- 流缓存这些值
- 迭代器只能使用一次?您不能返回到开始并再次计算该值吗
- 视图的值不会被缓存,但您可以反复计算它们
Stream
确实是一个惰性列表。事实上,在Scala中,流
是一个列表
,其尾部
是一个惰性val
。计算后,值保持计算状态并被重用。或者,正如您所说,这些值是缓存的
迭代器只能使用一次,因为它是指向集合的遍历指针,而不是集合本身。Scala中的特殊之处在于,您可以应用变换,例如map
和filter
,只需获得一个新的迭代器,它将仅在您请求下一个元素时应用这些变换
Scala曾经提供可以重置的迭代器,但这在一般情况下是很难支持的,并且他们没有将版本2.8.0
视图的查看方式与数据库视图非常相似。这是一系列转换,应用于集合以生成“虚拟”集合。正如您所说,每次需要从中获取元素时,都会重新应用所有转换
迭代器和视图都具有出色的内存特性Stream
很好,但在Scala中,它的主要优点是编写无限序列(特别是递归定义的序列)。通过确保不保留对其头的引用(例如,使用def
而不是val
来定义流,可以避免将所有流
保留在内存中
由于视图会受到惩罚,通常应在应用转换后强制它,或者如果与视图的总大小相比,只需提取很少的元素,则应将其保留为视图。迭代器
对于探测无限空间也非常方便,在可能的情况下,我通常更喜欢它们而不是溪流。流中真正的好处是缓存以前访问的值,这对于尝试实现类似斐波那契序列的东西是一个很大的好处,斐波那契序列是根据以前的值定义的。斐波那契是一个不太完美的例子,因为它只需要前两个值,而保留整个流是一种浪费。Ackermann函数可能是一个典型的例子。@JürgenStrobel Ackermann将导致糟糕的性能,因为流的索引访问是O(n)。但我同意fibonacci的说法。哦,对了。这使得流对于任何缓存方法来说都是一个糟糕的选择。这个答案非常清楚,它应该是文档的一部分。。。哦,事实上是这样!谢谢丹尼尔--------------