如何在Scala中复制迭代器?

gre*_*man 16 iterator scala

关于重复

这不是如何克隆迭代器的重复?

请不要盲目关闭这个问题,所谓的重复给出所有的答案不要工作.OP负责另一个问题,显然,答案符合HIS问题,但不是我的问题.

不是每个类似的问题都是重复的,在SE上有"扩展问题"这样的特征,唯一的方法是再次询问同一主题,以获得不同的,有效的答案.

问题

我有迭代器.我想得到它的复制(复制),然后我可以完全独立地继续原始和复制.

重要

通过反射或序列化进行复制是不行的(性能损失).

var list = List(1,2,3,4,5)
var it1 = list.iterator
it1.next()

var it2 = it1   // (*)
it2.next()

println(it1.next())
Run Code Online (Sandbox Code Playgroud)

这将简单地引用it1,因此当改变it1时,it2也会改变,反之亦然.

上面的例子使用List,我目前正在与HashMap斗争,但问题是一般的 - 只是迭代器.

方法#1

如果你编辑行(*)并写:

var it2 = it1.toList.iterator
Run Code Online (Sandbox Code Playgroud)

(这被建议作为链接问题中的解决方案)执行程序时抛出异常.

方法#2

"你拿这份清单......".不,我没有.我没有列表,我有迭代器.一般来说,我不知道任何关于迭代器的基础的集合,我唯一拥有的是迭代器.我必须"分叉"它.

Rex*_*err 15

您不能在不破坏它的情况下复制迭代器.合同iterator是它只能遍历一次.

您链接的问题显示如何获得两个副本以换取您已销毁的副本.您无法继续使用原始文件,但现在可以单独向前运行两个新副本.


Lui*_*hys 9

创建一个List可以复制而不会破坏它的迭代器非常容易:这基本上是iteratorList源中复制的方法的定义,fork添加了一个方法:

class ForkableIterator[A] (list: List[A]) extends Iterator[A] {
    var these = list
    def hasNext: Boolean = !these.isEmpty
    def next: A = 
      if (hasNext) {
        val result = these.head; these = these.tail; result
      } else Iterator.empty.next
    def fork = new ForkableIterator(these)
}
Run Code Online (Sandbox Code Playgroud)

使用:

scala> val it = new ForkableIterator(List(1,2,3,4,5,6))
it: ForkableIterator[Int] = non-empty iterator

scala> it.next
res72: Int = 1

scala> val it2 = it.fork
it2: ForkableIterator[Int] = non-empty iterator

scala> it2.next
res73: Int = 2

scala> it2.next
res74: Int = 3

scala> it.next
res75: Int = 2
Run Code Online (Sandbox Code Playgroud)

我看过这样做HashMap但看起来更复杂(部分是因为根据集合大小有不同的地图实现).所以最好使用上面的实现yourMap.toList.


Dan*_*ral 6

正如雷克斯所说,在不破坏它的情况下制作迭代器的副本是不可能的.那说,问题是duplicate什么?

var list = List(1,2,3,4,5)
var it1 = list.iterator
it1.next()

val (it1a, it1b) = it1.duplicate
it1 = it1a
var it2 = it1b
it2.next()

println(it1.next())
Run Code Online (Sandbox Code Playgroud)