2012-08-28 75 views
3

在斯卡拉殼我這樣做:斯卡拉理解與的foreach

import java.util._ 
import scala.collection.JavaConversions._ 

val t: SortedMap[String,Int] = new TreeMap[String,Int]() // produces an empty java.util.SortedMap 

t("a") = 1; t("b") = 2; t("A") = 3; t("0") = 4 

t // prints: res35: java.util.SortedMap[String,Int] = {0=4, A=3, a=1, b=2}, as expected 

t foreach println // also prints the (k,v) pairs in the same TreeMap sorted order 

但是,下面的語句不打印排序的順序對,它似乎打印出來的散列桶順序,(0 ,4)(b,2)(A,3)(A,1):

for ((k,v) <- t) printf("(%s,%d)%n", k, v) 

在其他的答案與用於和foreach似乎一個用於理解應該轉換成使用的foreach的像所以:

「換修真(P < - E)E0被翻譯成e.foreach {當p => E0}」

,但似乎並沒有被這裏發生了什麼。

需要注意的是,如果我創建一個從 TreeMap中,無論在foreach和用於生產(K,V)的排序順序對如我所料一個 SortedMap的。看起來像Java TreeMap爲scala轉換的某種方式是不同的。

有關爲何出現此差異的任何意見或想法?

回答

6

那麼,p(k,v)是不一樣的東西。您的-理解進行平移:

t.filter{ 
    case (k, v) => true 
    case _  => false 
}.map { 
    case (k, v) => printf("(%s,%d)$n") 
} 

一旦filter把它的手在Java集合,它變成了Scala的集合,並且不再分類。

作爲一個方面說明,在Scala 2.10上述不再是真實的,因爲它在編譯時檢測到沒有元素不是靜態類型的(k,v),並且不會生成過濾器。在這裏:

scala> for ((k,v) <- t) printf("(%s,%d)%n", k, v) 
<console>:15: warning: dead code following this construct 
       for ((k,v) <- t) printf("(%s,%d)%n", k, v) 
         ^
(0,4) 
(A,3) 
(a,1) 
(b,2) 

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> reify{for ((k,v) <- t) printf("(%s,%d)%n", k, v)} 
res4: reflect.runtime.universe.Expr[Unit] = 
Expr[Unit](scala.collection.JavaConversions.mapAsScalaMap(t).foreach(((x$1) => x$1: @unchecked match { 
    case scala.Tuple2((k @ _), (v @ _)) => scala.this.Predef.printf("(%s,%d)%n", k, v) 
}))) 

PS:身高超過JavaConvertersJavaConversions

+0

謝謝Daniel,很好的回答! –

+2

@BobYacobellis我只是做得更好。 :-) –

+0

我看到我真正想要的陳述是這樣的:'for(kv <-t)printf(「(%s,%d)%n」,kv._1,kv._2)' –