Question

I have a mutable map containing another mutable map, both with default values. After I assign a value to one key in the enclosed map, its default value seems to change. I.e. I expected anotherDefault to have the value Map(1 -> default), NOT Map(1 -> something).

Why is this happening?

scala> import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{Map=>MMap}

scala> val amap = Map[Int, MMap[Int, String]]().withDefaultValue(MMap().withDefaultValue("default"))
amap: scala.collection.immutable.Map[Int,scala.collection.mutable.Map[Int,String]] = Map()

scala> val bmap = amap(2)
bmap: scala.collection.mutable.Map[Int,String] = Map()

scala> bmap(1)
res17: String = default

scala> bmap(1) = "something"

scala> val anotherDefault = amap(3)
anotherDefault: scala.collection.mutable.Map[Int,String] = Map(1 -> something)
Was it helpful?

Solution

The outer map (amap) is creating a single instance of the inner map to use as the default. When you access this via val bmap = amap(2), then modify bmap, you are modifying the single default map used by amap. When you call amap(3), you then get back this default map, which is now a map with the key/value pair (1 -> "something").

What you probably want is withDefault, not withDefaultValue, although it needs some extra argument/type specification to work:

val amap = Map[Int, MMap[Int, String]]().withDefault(x => MMap[Int, String]().withDefaultValue("default"))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top