2012-08-28 76 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)' –