Scala 2.13.10中Iterator调用size后next未报错的原因咨询
问题:Scala迭代器调用size后仍能next的疑惑
我在Scala 2.13.10本地解释器中执行了以下代码:
scala> val it = Iterator("a", "number", "of", "words") val it: Iterator[String] = <iterator> scala> it.size val res0: Int = 4 scala> it.next() val res14: String = a
我原本认为调用it.size会遍历整个迭代器,之后调用it.next()应该抛出异常,因为Scala官方文档明确说明:
it.size 返回迭代器包含的元素数量。注意:执行此操作后,迭代器会处于末尾位置!
原因分析
你忽略了Scala迭代器的类型差异:
- 你通过
Iterator(...)直接创建的是不可变迭代器(scala.collection.immutable.Iterator)。这类迭代器的所有遍历操作(比如size、foreach)都不会修改原迭代器的内部状态——它们会在遍历过程中生成临时迭代器实例,原迭代器始终保持在起始位置,所以后续调用next()还能正常获取第一个元素。 - 官方文档里描述的“调用
size后迭代器耗尽”,针对的是可变迭代器(比如ArrayBuffer、ListBuffer这类可变集合的迭代器)。这类迭代器是有状态的,遍历操作会直接移动自身的指针,耗尽后无法重置,再调用next()就会抛出NoSuchElementException。
验证示例
如果创建一个可变迭代器,就能复现文档描述的行为:
scala> val mutableIt = scala.collection.mutable.ArrayBuffer("a", "number", "of", "words").iterator val mutableIt: Iterator[String] = <iterator> scala> mutableIt.size val res0: Int = 4 scala> mutableIt.next() java.util.NoSuchElementException: next on empty iterator at scala.collection.mutable.AbstractIterator.next(AbstractIterator.scala:134) ... 32 elided
内容的提问来源于stack exchange,提问作者Dan The Man
相关产品推荐
相关产品推荐

