我正在尝试理解this answer,与使用默认值的地图有关:
val lists = new mutable.HashMap[String,List[Int]].withDefaultValue(Nil)
lists("dog") ::= 13
lists("cat") ::= 14
lists("dog") ::= 15 //(13, 15)
据我所知,scala使用“嵌套”函数来表示不可变列表。一个不幸的副作用是迭代不可变列表会返回逆序中的元素。
为了避免相反的顺序,我尝试使用ArrayBuffer实现这个:
val lists = new mutable.HashMap[String,mutable.ArrayBuffer[Int]].withDefault(_=>ArrayBuffer())
lists("dog").append(1)
println( lists("dog") ) //prints "ArrayBuffer()"
不幸的是,这不起作用。似乎scala实际上并没有将的默认值放回到地图上,并且不断返回空的ArrayBuffers
最后,我使用以下代码:
val lists1 = new mutable.HashMap[String,mutable.ArrayBuffer[Int]]
val lists= lists1.withDefault( x=>{val n= mutable.ArrayBuffer[Int](); lists1(x)=n; n})
这有效,但似乎不必要地复杂。有更好的解决方案吗?
答案 0 :(得分:2)
::=
真正起作用有点不明显。它在列表中使用指定的函数::
(prepend),然后将函数的结果(=
)分配回指定键下的映射。
如果你想快速追加,不仅是prepends,并且仍然有一个不可变的集合作为地图中的值,请使用Vector
:
val map = mutable.Map[String, Vector[Int]]().withDefaultValue(Vector())
现在,Vector
有:+
method,它会返回附加了元素的向量副本,这是完美的。这意味着,当您考虑::=
的解释时,您可以这样做:
map("dog") :+= 7
map("cat") :+= 3
map("dog") :+= 11
结果:
scala> map("cat")
res4: Vector[Int] = Vector(3)
scala> map("dog")
res5: Vector[Int] = Vector(7, 11)