Reputation: 1139
What is happening here?
Welcome to Scala 2.13.5 (OpenJDK 64-Bit Server VM, Java 1.8.0_312).
...
> import scala.collection.mutable.{Map => MMap, ListBuffer => MList}
import scala.collection.mutable.{Map=>MMap, ListBuffer=>MList}
> val m = MMap[String, MList[String]]().withDefaultValue(MList[String]())
val m: scala.collection.mutable.Map[String,scala.collection.mutable.ListBuffer[String]] = Map()
> m("a")
val res0: scala.collection.mutable.ListBuffer[String] = ListBuffer()
> m("a").addOne("b")
val res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(b)
> m
val res2: scala.collection.mutable.Map[String,scala.collection.mutable.ListBuffer[String]] = Map()
> m.keys
val res3: Iterable[String] = Set()
> m("a")
val res4: scala.collection.mutable.ListBuffer[String] = ListBuffer(b)
some of the text above has been removed for readability
Upvotes: 1
Views: 83
Reputation: 2638
Because your default value is mutable, you just mutated the default value. But you never inserted anything in the Map
that is why you don't see anything inside.
m("a")
is syntactic sugar for m.apply("a")
which since there is no value for that key, but there is a default value set, it results in the default value you just set earlier.
If you'll check the withDefaultValue
doc, you'll see this:
The same map with a given default value. Note: The default is only used for
apply
. Other methods likeget
,contains
,iterator
,keys
, etc. are not affected bywithDefaultValue
. Invoking transformer methods (e.g.map
) will not preserve the default value.
Since ListBuffer
is mutable you are directly mutating the contents of the default value, when using the addOne
method on it.
So now every key that has no value in the Map
will result in ListBuffer(b)
:
scala> m("a")
val res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(b)
scala> m("c")
val res2: scala.collection.mutable.ListBuffer[String] = ListBuffer(b)
scala> m("whatever")
val res3: scala.collection.mutable.ListBuffer[String] = ListBuffer(b)
You should use an immutable List
as the default value if you want it to remain unchanged.
Upvotes: 2