Iterator.continually: 第一个元素的特殊处理。

问题描述 投票:3回答:1

我有一个 Iterator 基于一个重复的函数调用。

anObject.synchronized {
    Iterator.continually { 
        anObject.wait()      // skip this call for the 1st iteration
        Try(anObject.foo()) 
    }.dropWhile(_.isFailure).next()
    anObject.notifyAll()
}

我想在第一次迭代时不调用 anObject.wait(). 当然,我可以做如下的东西。

anObject.synchronized {
    if (Try(anObject.foo()).isFailure) {
        Iterator.continually { 
            anObject.wait()
            Try(anObject.foo()) 
        }.dropWhile(_.isFailure).next()
    }
    anObject.notifyAll()
}

有没有更优雅或更标准的方法来达到同样的目的(跳过第一次迭代的函数调用)?

PS 当需要打印一个带定界符的列表时,也会出现类似的任务。

scala> List("a", "b", "c").mkString(", ")
res1: String = a, b, c

所以,我希望我的问题也能有一些解决方法

multithreading scala iterator synchronized
1个回答
2
投票

也许可以创建一个新的迭代器,检查第一个元素。

def continually[A](firstElem: => A)(elem: => A): Iterator[A] = new AbstractIterator[A] {
    var isFirst = true
    def hasNext = true
    def next(): A = if (isFirst) { isFirst = false; firstElem } else elem
  }

continually("a")("b").take(3).foreach(print)
// abb

2
投票

你可以改变 .continually.tabulate 只要2,147,483,647不会是一个有意义的限制迭代次数。

anObject.synchronized {
    Iterator.tabulate { n => 
        if (n != 0) anObject.wait()  // skip 1st iteration
        Try(anObject.foo()) 
    }.dropWhile(_.isFailure).next()
    anObject.notifyAll()
}
© www.soinside.com 2019 - 2024. All rights reserved.