在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的某种方式是不同的。
有关此差异原因的任何意见或想法?
答案 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
。