如何克隆迭代器?

时间:2011-03-07 13:08:02

标签: scala iterator

假设我有一个迭代器:

val it = List("a","b","c").iterator

我想要一份副本;我的代码是:

val it2 = it.toList.iterator

这是正确的,但似乎并不好。还有其他API吗?

2 个答案:

答案 0 :(得分:19)

您要查找的方法是duplicate

scala> val it = List("a","b","c").iterator
it: Iterator[java.lang.String] = non-empty iterator

scala> val (it1,it2) = it.duplicate
it1: Iterator[java.lang.String] = non-empty iterator
it2: Iterator[java.lang.String] = non-empty iterator

scala> it1.length
res11: Int = 3

scala> it2.mkString
res12: String = abc

答案 1 :(得分:9)

警告:至少从Scala 2.9.0开始,这会使原始迭代器变空。您可以 val ls = it.toList; val it1 = ls.iterator; val it2 = ls.iterator 获得两份副本。或者使用复制(也适用于非列表)。

Rex的答案在于本书,但实际上你的原始解决方案对于scala.collection.immutable.List来说是最有效的。

列表迭代器可以使用该机制进行复制,基本上没有开销。这可以通过快速查看scala.collection.immutable.LinearSeq中的iterator()的实现来确认。 toList方法的定义,它简单地返回后备Seq的_.toList,如果它是List(就像你的情况那样)是标识。

在调查你的问题之前我没有意识到List迭代器的这个属性,我非常感谢这些信息......除此之外,它意味着许多“列表修改”算法可以通过Scala不可变来有效地实现列出使用迭代器作为鹅卵石。