扩展 Iterator 可能比您实际需要做的工作更多。让我们回滚一点。
你有一些 MyAlgorithm1 类型的有状态对象
val alg1 = new MyAlgorithm1(args)
现在你希望在它上面重复调用一些函数,这将改变它的状态并返回一些值。最好不要通过让您的对象实现 Iterator 来建模,而是通过创建一个处理迭代的新对象来建模。Scala 标准库中最简单的可能是 Stream。这是一个从您的算法创建结果流的对象。
val alg1Stream:Stream[Step] = Stream.continually(alg1.next())
现在,如果您想从该流中重复获取结果,那么它就像
for(step<-alg1Stream){
// do something
}
或等效地
alg1Stream.forEach{
//do something
}
现在假设我们也将 myAlgorithm2 封装为一个流
val alg2=new MyAlgorithm2(args)
val alg2Stream:Stream[Step] = Stream.continually(alg2.next())
然后我们只需要某种方式来交错流,然后我们可以说
for(step<-interleave(alg1Stream, algStream2)){
// do something
}
可悲的是,快速浏览标准库,没有发现 Stream interleaving 函数。很容易写一个
def interleave[A](stream1:Stream[A], stream2:Stream[A]):Stream[A] ={
var str1 = stream1
var str2 = stream2
var streamToUse = 1
Stream.continually{
if(streamToUse == 1){
streamToUse = 2
val out = str1.head
str1 = str1.tail
out
}else{
streamToUse = 1
val out = str2.head
str2 = str1.tail
out
}
}
}
这构造了一个在两个流之间反复交替的流,从适当的流中获取下一个结果,然后为下一次获取设置它的状态。请注意,这种交错只适用于无限流,我们需要一个更聪明的来处理可以结束的流,但为了解决问题,这很好。