4

Scala シェルでは、次のようにしました。

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 に関連する他の回答では、 for 内包表記は次のように foreach の使用に変換されることになっているようです。

「(p <- e) e0 の for 内包表記は e.foreach { case p => e0 } に変換されます」

しかし、それはここで起こっていることではないようです。

scala TreeMap からscala SortedMapを作成すると、foreach と for の両方が期待どおりにソートされた順序で (k,v) ペアを生成することに注意してください。Java TreeMap が scala 用に変換される方法が異なるようです。

この不一致の理由について何かコメントやアイデアはありますか?

4

1 に答える 1

7

まあ、同じものではありませんp(k,v)あなたの理解は次のように翻訳されます:

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

filterJava コレクションに手を加えると、それは 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ます。

于 2012-08-28T03:04:30.453 に答える