我一直在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
被++
编辑在一起时,会实例化一个新的TreeMap
,然后来自TreeMap
的所有键值对添加了。由于TreeMap
是不可变的,为什么我们不能从TreeMap
之一开始,只是从另一个中添加项目?这只是因为++
适用于不可变类型和可变类型,因此我们需要制作防御性副本,而某些集合可能会有更有效的策略吗?
答案 0 :(得分: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) (_ + _)
所以我们从a
开始,将b
的每个元素折叠到其中以获得最终结果。
换句话说,它似乎完全符合您的预期。或者我错过了什么?