Scala归因于默认地图

时间:2014-01-16 11:33:44

标签: scala map default

我正在尝试理解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})

这有效,但似乎不必要地复杂。有更好的解决方案吗?

1 个答案:

答案 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)