2012-03-15 27 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 
} 

我不明白演员,但除此之外。例如,当两个TreeMap s是++ - 合在一起时,实例化新的TreeMap,然后添加来自TreeMaps的所有键值对。由于TreeMap是不可变的,我们为什么不能从TreeMap之一开始,只是添加其他项目?这是因为++适用于不可变和可变类型,所以我们需要制作一个防御副本,并且一些集合可能有更有效的策略?

回答

1

如果这是我们的代码:

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

然后++TreeMap定义为:

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

所以我们先从ab到它的每个元素折叠,以获得最终结果。

换句话说,它似乎正在做你期望的。或者我错过了什么?

+0

你是对的 - 我不知道我是如何错过的。想到更多的建设者可能是这样写的,所以它可以处理地图,过滤器等。 – schmmd 2012-03-15 16:20:48

+0

正确的 - 并转换为不同的集合。 – schmmd 2012-03-15 16:43:51