2011-02-03 74 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迭代器已經發展到了盡頭。