2011-02-03 64 views
10

考虑:斯卡拉迭代器图和

val list = List("one","two","three")  
val it = list.toIterator 

我可以运行:

list map ("_" +) -> List(_one, _two, _three) 
for (i <- list) yield("_" + i) -> List(_one, _two, _three) 

如果我运行的迭代器一样,我得到:

it map ("_" +) -> Iterator[java.lang.String] = empty iterator 
for (i <- it) yield("_" + i) -> Iterator[java.lang.String] = empty iterator 

不应该在我运行map/for之后,我返回另一个(非空)Iterator [String]?

回答

15
scala> def ints(n: Int): Stream[Int] = n #:: ints(n + 1) 
ints: (n: Int)Stream[Int] 

scala> val list = List("one","two","three") 
list: List[java.lang.String] = List(one, two, three) 

scala> val it = list.toIterator 
it: Iterator[java.lang.String] = non-empty iterator 

scala> it map ("_" +) 
res24: Iterator[java.lang.String] = non-empty iterator 

scala> it map ("_" +) 
res25: Iterator[java.lang.String] = non-empty iterator 

scala> for (i <- it) yield("_" + i) 
res26: Iterator[java.lang.String] = non-empty iterator 

也许你用过你的迭代器?

scala> res26.foreach{println} 
_one 
_two 
_three 

scala> res26 
res28: Iterator[java.lang.String] = empty iterator 

由于迭代器是有状态的,而不是重置,一旦你使用它,它是空的,不能再使用。

相反,你可以使用视图:

scala> val v = list.view 
v: java.lang.Object with scala.collection.SeqView[java.lang.String,List[java.lang.String]] = SeqView(one, two, three) 

scala> v map ("_" +) 
res29: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...) 

scala> for (i <- v) yield("_" + i) 
res30: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...) 

scala> res29.foreach{println} 
_one 
_two 
_three 

scala> res29 
res32: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...) 

scala> res29.foreach{println} 
_one 
_two 
_three 
+1

你说得对!在运行示例之前,我必须使用迭代器。谢谢! :) – ssanj 2011-02-03 05:49:12

3

Iterators

还有的foreach方法对迭代器和穿越藏品同样的方法之间的一个重要区别:当调用一个迭代器,foreach将在其结束后离开迭代器,当它完成。因此,在同一迭代器上再次调用next将失败,并显示NoSuchElementException。相比之下,在集合上调用foreach时,集合中元素的数量保持不变(除非传递的函数添加到删除元素,但由于可能导致令人惊讶的结果,因此不鼓励)。

...

正如你所看到的,调用it.map之后,it迭代器已经发展到了尽头。