scala中的Iterator
和Iterable
之间有什么区别?
我认为Iterable
表示我可以迭代的集合,Iterator
是可迭代集合中某个项目的“指针”。
但是,Iterator
具有forEach
,map
,foldLeft
等功能。它可以通过Iterable
转换为toIterable
。例如,scala.io.Source.getLines
返回Iterator
,而不是Iterable
。
但我无法在groupBy
Iterator
上Iterable
,我可以在Iterator
上执行此操作。
那么,这两者之间的关系是什么,Iterable
和{{1}}?
答案 0 :(得分:62)
简而言之:Iterator
确实有州,而Iterable
则没有。
请参阅两者的API文档。
可迭代集合的基本特征。
这是定义迭代器的所有Scala集合的基本特征 逐步逐步收集集合元素的方法。 [...]这个特性通过步进实现了Iterable的foreach方法 通过使用迭代器的所有元素。
迭代器是允许迭代序列的数据结构 元素。他们有一个hasNext方法来检查是否有下一个 元素可用,以及返回下一个元素的下一个方法 并将其从迭代器中丢弃。
迭代器是可变的:它上面的大多数操作都会改变它的状态。而 它通常用于迭代集合的元素 也可以在没有任何集合支持的情况下使用(参见 伴侣对象上的构造函数。)
使用Iterator
,您可以停止迭代,如果需要,可以稍后继续。如果您尝试使用Iterable
执行此操作,它将再次从头部开始:
scala> val iterable: Iterable[Int] = 1 to 4
iterable: Iterable[Int] = Range(1, 2, 3, 4)
scala> iterable.take(2)
res8: Iterable[Int] = Range(1, 2)
scala> iterable.take(2)
res9: Iterable[Int] = Range(1, 2)
scala> val iterator = iterable.iterator
iterator: Iterator[Int] = non-empty iterator
scala> if (iterator.hasNext) iterator.next
res23: AnyVal = 1
scala> if (iterator.hasNext) iterator.next
res24: AnyVal = 2
scala> if (iterator.hasNext) iterator.next
res25: AnyVal = 3
scala> if (iterator.hasNext) iterator.next
res26: AnyVal = 4
scala> if (iterator.hasNext) iterator.next
res27: AnyVal = ()
请注意,我没有在take
上使用Iterator
。原因是它使用起来很棘手。 hasNext
和next
是唯一可以保证在Iterator
上按预期工作的两种方法。再次查看Scaladoc:
特别重要的是要注意,除非另有说明, 在调用方法之后,永远不应该使用迭代器。他们俩 最重要的例外也是唯一的抽象方法:next和 hasNext。
这两种方法都可以被调用任意次,而不必 丢弃迭代器。请注意,即使hasNext可能会导致变异 - 例如,当从输入流迭代时,它将阻塞直到 流已关闭或某些输入可用。
考虑这个例子是为了安全和不安全使用:
def f[A](it: Iterator[A]) = { if (it.hasNext) { // Safe to reuse "it" after "hasNext" it.next // Safe to reuse "it" after "next" val remainder = it.drop(2) // it is *not* safe to use "it" again after this line! remainder.take(2) // it is *not* safe to use "remainder" after this line! } else it }
答案 1 :(得分:5)
Martin Odersky和Lex Spoon的另一个解释:
foreach方法之间有一个重要的区别 可遍历集合上的迭代器和相同方法:调用时 对于迭代器,foreach会在迭代器结束时离开迭代器 完成。因此,在同一个迭代器上再次调用next将失败 NoSuchElementException异常。相比之下,当收集一个集合时, foreach使集合中元素的数量保持不变 (除非传递的函数添加删除元素,但这是 气馁,因为它可能导致令人惊讶的结果)。
来源:http://www.scala-lang.org/docu/files/collections-api/collections_43.html
另请注意(感谢Wei-Ching Lin提供此提示)Iterator
扩展了TraversableOnce
特征,Iterable
没有。