0

おそらく簡単な質問ですが、API から満足のいく答えが見つかりませんでした。私は素敵なコードを書こうとしているわけではありませんが、特定のことがどのように機能するかについてもっと学ぼうとしています:

最初の HashMap を作成しました。任意のリストから、マップを使用して HashMaps のリストを作成したいと思います。.map 関数内の HashMap に (キー、値) ペアを追加します。したがって、このリストの後続のインデックスでは、格納された HashMap のサイズが 1 ずつ増加する必要があります (つまり、list(i).size == list(i+1).size - i ごとに 1)。

しかし、次のコードを切り取ると、すべて等しいマップ (つまり、完全な HashMap) のリストが得られます。ただし、成長する初期 HashMap を出力すると、すべてが正しいように見えます。

scala> import scala.collection.mutable.HashMap

val m = new HashMap[Int, Int]

List(1,2,3,4) map {e =>
    println(m)
    val newM = m += e -> (e+2)
    newM
}
Map()
Map(1 -> 3)
Map(1 -> 3, 2 -> 4)
Map(3 -> 5, 1 -> 3, 2 -> 4)

import scala.collection.mutable.HashMap
m: scala.collection.mutable.HashMap[Int,Int] = Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4)
res7: List[scala.collection.mutable.HashMap[Int,Int]] = List(Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4),     Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4))

私が期待したのは次のようなものでした

List(Map(1 -> 2), Map(1 -> 2, 2 -> 4), Map(1 -> 2, 2 -> 4, 3 -> 5), Map(1 -> 2, 2 -) > 4、3 -> 5、4 -> 6))

ジェネレーティブ for ループを使用した同等の (だと思います) バージョンでは、まったく同じ結果が得られます。

scala> for {
    i <- 1 to 4
    val newM = m += i -> (i+2)
} yield newM
 res10: scala.collection.immutable.IndexedSeq[scala.collection.mutable.HashMap[Int,Int]] = Vector(Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4))

scala> for (i <- 1 to 4) yield {
    val newM = m += i -> (i+2)
    println(m)
    newM
} 
Map(1 -> 3)
Map(1 -> 3, 2 -> 4)
Map(3 -> 5, 1 -> 3, 2 -> 4)
Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4)
res11: scala.collection.immutable.IndexedSeq[scala.collection.mutable.HashMap[Int,Int]] = Vector(Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4), Map(3 -> 5, 4 -> 6, 1 -> 3, 2 -> 4))

基本的なステップが欠けていると思いますが、どれがわかりません。さらに助けていただければ幸いです。

後続の質問: (キー、値) ペアが出力される順序は明らかに常に同じです (ただし、それらが要素であった順序ではありませんが、いずれにせよ Map からこれを期待していません。これは自然なことです)。常にそうであるように見えるペアが保存されると、バックグラウンドで何が起こりますか?

4

1 に答える 1

4

m変更可能な HashMap です。

この+=メソッドは、まったく同じマップに新しい要素を追加し、マップを返します。

マップnewMに という名前を付けましたが、これはニシンです! まったく同じマップmです。だから、それらはすべてただmです。

本当にコピーが必要な場合は、お電話くださいclone(m例: val newM = (m += e -> (e+2)).clone)。

または、不変のマップを構築したい場合は、次のscanメソッドを使用できます。

List(1,2,3,4).scanLeft(collection.immutable.HashMap[Int,Int]()){ (m,e) => m + (e -> (e+2)) }

これはアイテム (この場合は空のマップ) を受け取り、その上に段階的に構築し、完了すると履歴全体を返します。

res7: List[scala.collection.immutable.HashMap[Int,Int]]
  = List(Map(), Map(1 -> 3), Map(1 -> 3, 2 -> 4),
         Map(1 -> 3, 2 -> 4, 3 -> 5), Map(1 -> 3, 2 -> 4, 3 -> 5, 4 -> 6))

さらに良いことに、あなたはできる

List(1,2,3,4).map(e => e -> (e+2)).toMap

構築プロセスを気にせずに最終的なマップを取得できます。

于 2012-04-04T22:10:27.820 に答える