我尝试创建一个带有默认值的可变Map
,当请求的元素尚未在地图中时,该默认值会创建一个新的ListBuffer
。但是,虽然新地图作为默认值返回,但它不会保留在地图中。也许这就是它的工作方式,我想,但是当我用Int
而不是ListBuffer
进行测试时,它完全符合我的要求。这里有一些代码来解释我的意思 - 我做错了什么?
首先,它在使用Map[Int]
:
scala> val a = collection.mutable.Map(1 -> 1).withDefault(i => 0)
a: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1)
scala> a(1) += 1 // adding to an existing element works as expected
scala> a
res48: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)
scala> a(2) += 1 // what about adding to a non-existing element?
scala> a // the new element has been added to the map
res50: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2, 2 -> 1)
现在使用Map[ListBuffer[Int]]
:
scala> val b = collection.mutable.Map(1 -> collection.mutable.ListBuffer[Int]()).withDefault(i => collection.mutable.ListBuffer.empty[Int])
b: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]] = Map(1 -> ListBuffer())
scala> b(1) += 1 // appending to an existing element works as expected
res51: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1)
scala> b
res52: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]] = Map(1 -> ListBuffer(1))
scala> b(2) += 1 // but appending to a non-existing element...
res53: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1)
scala> b // leaves the map unchanged
res54: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]] = Map(1 -> ListBuffer(1))
答案 0 :(得分:3)
区别在于:
在第一种情况下,a(2)
是Int
。由于Int
没有+=
方法,a(2) += 1
等同于a(2) = a(2) + 1
,因此a.update(2, a(2) + 1)
。 update
实际上更改了地图。
但是ListBuffer[Int]
确实采用了+=
方法,因此您的调用是a(2).+=(1)
,并且您没有将a(2)
设置为任何内容!
答案 1 :(得分:1)
当密钥不存在时,您可以使用getOrElseUpdate(key: A, op: => B)
来创建ListBuffer的新实例。
E.g。
val m = collection.mutable.Map[Int, ListBuffer[Int]]()
m.getOrElseUpdate(1, ListBuffer()) += 1