2012-03-15 6 views
2

私はScalaコードを掘り下げました。 TreeMapは次のビルダークラスを使用しています。マップビルダーは毎回地図を最初から再作成しますか?

class MapBuilder[A, B, Coll <: scala.collection.GenMap[A, B] with scala.collection.GenMapLike[A, B, Coll]](empty: Coll) 
extends Builder[(A, B), Coll] { 
    protected var elems: Coll = empty 
    def +=(x: (A, B)): this.type = { 
    elems = (elems + x).asInstanceOf[Coll] 
     // the cast is necessary because right now we cannot enforce statically that 
     // for every map of type Coll, `+` yields again a Coll. With better support 
     // for hk-types we might be able to enforce this in the future, though. 
    this 
    } 
    def clear() { elems = empty } 
    def result: Coll = elems 
} 

私はキャストを理解していませんが、それ以外の点です。たとえば、2つのTreeMap++ -edである場合、新しいTreeMapがインスタンス化され、次にTreeMapのすべてのキーと値のペアが追加されます。 TreeMapは不変なので、TreeMapのいずれかから開始して、もう一方のアイテムを追加するだけの理由はありますか?これは単に++が不変型と可変型の両方で動作するため防御的なコピーを作成する必要があり、一部のコレクションではより効率的な戦略があるからですか?

答えて

1

これは我々のコードの場合:次に++は次のようにTreeMapに定義されている

val a = TreeMap(1->'a, 2->'b) 
val b = TreeMap(3->'c, 4->'d) 
val c = a ++ b 

override def ++[B1 >: B] (xs: GenTraversableOnce[(A, B1)]): TreeMap[A, B1] = 
    ((repr: TreeMap[A, B1]) /: xs.seq) (_ + _) 

だから我々はaから始まり、最終的な結果を得るために、それにbの各要素を折ります。

言い換えれば、それはまさにあなたが期待したことをしているようです。それとも私は何かが恋しい?

+0

あなたは絶対に正しいです - 私はそれを逃したか分かりません。ビルダーはおそらくそれがマップやフィルターなどを扱うことができるように書かれています。 – schmmd

+0

右の - 別のコレクションに変換するため。 – schmmd

関連する問題