我想以功能方式实现迭代器特征,即不使用var。怎么做?
假设我有一个外部库,可以通过调用一个函数来获取一些元素,getNextElements(numOfElements: Int):Array[String]
并且我想使用该函数实现一个Iterator,但不使用表示“当前”数组的变量(在我的情况下为var缓冲区)。我该如何以功能方式实现它?
class MyIterator[T](fillBuffer: Int => Array[T]) extends Iterator[T] {
var buffer: List[T] = fillBuffer(10).toList
override def hasNext(): Boolean = {
if (buffer.isEmpty) buffer = fillBuffer(10).toList
buffer.nonEmpty
}
override def next(): T = {
if (!hasNext()) throw new NoSuchElementException()
val elem: T = buffer.head
buffer = buffer.tail
elem
}
}
class Main extends App {
def getNextElements(num: Int): Array[String] = ???
val iterator = new MyIterator[String](getNextElements)
iterator.foreach(println)
}
迭代器是可变的,至少在没有返回状态变量的接口的情况下是可变的,因此,一般来说,如果不进行某种形式的更改,就无法直接实现接口。
就是说,Iterator
伴随对象中有一些非常有用的功能,这些功能可让您隐藏变异并简化实现。我会像这样实现您的:
Iterator.continually(getNextElements(10)).flatten
getNextElements(10)
每当需要填充缓冲区时就会调用此方法。将flatten
其从更改Iterator[Array[A]]
为Iterator[A]
。
注意,这将返回一个无限迭代器。您的问题没有说明检测源元素的结尾,但是我通常使用来实现takeWhile
。例如,如果getNextElements
在没有更多元素的情况下返回空数组,则可以执行以下操作:
Iterator.continually(getNextElements(10)).takeWhile(!_.isEmpty).flatten
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句