我有一段代码(sentences
此处为iterator
):
def count() = {
var count = 0
for(sentence <- sentences.toStream) count += sentence.words.size
count
}
并测试:
// first
val wordCount1 = wordCounter.count()
wordCount1 must_== 10
// second time - should be same result
val wordCount2 = wordCounter.count()
wordCount2 must_== 10 // fails: result is 0
上次测试失败:
'0' is not equal to '10'
Expected :10
Actual :0
但是由于我在上面的代码中使用了sentences.toStream
,我认为stream
就是{我可以重用它,理论上)。
问:为什么会失败?
修改
我希望toStream
会有所帮助。就像描述here :( ...“你可以多次遍历相同的Stream
”......)。这就像我从不触摸迭代器,我处理流。
但是我得到了sentences.toStream
使用了 sentence-iterator
所以我不能再使用它了。我只是期望在toStream
上执行iterator
时做一个逻辑,比如在没有触及迭代器本身的情况下获取流到迭代器的'链接'。确定..
答案 0 :(得分:4)
它失败,因为sentences
Iterator
已被支出。除了Iterator
和next
方法之外,我们不应该在调用hasNext
上的方法之后调用scala> val it = Iterator(1,2,3)
it: Iterator[Int] = non-empty iterator
scala> it.foreach(println(_))
1
2
3
scala> it.foreach(println(_))
scala>
。
一个简单的例子说明了这一点:
sentences
在你的情况下toStream
已经在第一个电话上消耗了,而在第二个电话上是空的,大小为0。
在其上调用Stream
不会改变这一点。你得到一个空的sentences
。如果您想重新使用val l = sentences.toList
,请在调用count之前将其分配给{{1}}的列表。
答案 1 :(得分:3)
实际上toStream
有帮助。我只是将代码更改为期望stream
而不是iterator
,以便不在第二个+遍历中尝试从'dead'迭代器创建流。
然后我的解决方案是:
val stream = new SentenceFileReader("two_lines_file.txt").toStream
val wordCounter = new WordCounter(stream) // now it accepts stream but not iterator
// first
val wordCount1 = wordCounter.count()
wordCount1 must_== 10
// second time - same result
val wordCount2 = wordCounter.count()
wordCount2 must_== 10