Scala的理解与foreach

时间:2012-08-28 01:44:16

标签: scala

在Scala shell中我做到了:

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)

在与for和foreach相关的其他答案中,似乎理解应该转化为使用foreach,如下所示:

  

“对(p < - e)e0的理解被翻译为e.foreach {case p =&gt; e0}”

但这似乎不是这里发生的事情。

请注意,如果我从 scala TreeMap创建 scala SortedMap,则foreach和for按照预期排序顺序生成(k,v)对。似乎Java TreeMap被转换为scala的某种方式是不同的。

有关此差异原因的任何意见或想法?

1 个答案:

答案 0 :(得分: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:首选JavaConverters超过JavaConversions