Update a mutable map with default value in Scala
dictionary, scala
Solution
This is not an implicit conversion - it is a desugaring. Writing:
x += 1
desugars to:
x = x + 1
if the class of `x` does not have a `+=` method defined on it.
In the same way:
counts("a") += 1
desugars to:
counts("a") = counts("a") + 1
because `counts("a")` is an `Int`, and `Int` does not have a `+=` method defined.
On the other hand, writing:
x(expression1) = expression2
desugars to a call to the `update` method in Scala:
x.update(expression1, expression2)
Every mutable `Map` has an `update` method defined - it allows setting keys in the map.
So the entire expression is desugared to:
list.foreach(x => counts.update(x, counts(x) + 1))
This `+=` is not to be confused with the `+=` method on `mutable.Map`s in Scala. That method updates the entry in the map if that key already existed, or adds a new key-value pair. It returns the `this` reference, that is, the same map, so you can chain `+=` calls. See ScalaDoc or the source code.
Problem
Consider the following code that counts the frequency of each string in the list and stores the results in the mutable map. This works great, but I don't understand where the += method is defined?! Is this some weird implicit conversion thing or what? I saw this code somewhere but it didn't include an explanation for the +=. ``` val list = List("a", "b", "a") val counts = new scala.collection.mutable.HashMap[String, Int]().withDefaultValue(0) list.foreach(counts(_) += 1) counts //> res7: scala.collection.mutable.Map[String,Int] = Map(a -> 2, b -> 1) ``` The apply of map returns an Int, but Int doesn't have a += and this method updates the map with a new value, so it looks as if the apply returns a mutable integer that has a += method...