How can I convert immutable.Map to mutable.Map in Scala?

ScalaDictionaryScala 2.8

Scala Problem Overview


How can I convert immutable.Map to mutable.Map in Scala so I can update the values in Map?

Scala Solutions


Solution 1 - Scala

The cleanest way would be to use the mutable.Map varargs factory. Unlike the ++ approach, this uses the CanBuildFrom mechanism, and so has the potential to be more efficient if library code was written to take advantage of this:

val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*) 

This works because a Map can also be viewed as a sequence of Pairs.

Solution 2 - Scala

val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap

Solution 3 - Scala

Starting Scala 2.13, via factory builders applied with .to(factory):

Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")

Solution 4 - Scala

How about using collection.breakOut?

import collection.{mutable, immutable, breakOut}
val myImmutableMap = immutable.Map(1->"one",2->"two")
val myMutableMap: mutable.Map[Int, String] = myImmutableMap.map(identity)(breakOut)

Solution 5 - Scala

There is a variant to create an empty mutable Map that has default values taken from the immutable Map. You may store a value and override the default at any time:

scala> import collection.immutable.{Map => IMap}
//import collection.immutable.{Map=>IMap}

scala> import collection.mutable.HashMap
//import collection.mutable.HashMap

scala> val iMap = IMap(1 -> "one", 2 -> "two")
//iMap: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,one), (2,two))

scala> val mMap = new HashMap[Int,String] {      
     | override def default(key: Int): String = iMap(key)
     | }
//mMap: scala.collection.mutable.HashMap[Int,String] = Map()

scala> mMap(1)
//res0: String = one

scala> mMap(2)
//res1: String = two

scala> mMap(3)
//java.util.NoSuchElementException: key not found: 3
//	at scala.collection.MapLike$class.default(MapLike.scala:223)
//	at scala.collection.immutable.Map$Map2.default(Map.scala:110)
//	at scala.collection.MapLike$class.apply(MapLike.scala:134)
//	at scala.collection.immutable.Map$Map2.apply(Map.scala:110)
//	at $anon$1.default(<console>:9)
//	at $anon$1.default(<console>:8)
//	at scala.collection.MapLike$class.apply(MapLike.scala:134)....

scala> mMap(2) = "three"

scala> mMap(2)          
//res4: String = three

Caveat (see the comment by Rex Kerr): You will not be able to remove the elements coming from the immutable map:

scala> mMap.remove(1)
//res5: Option[String] = None

scala> mMap(1)
//res6: String = one

Solution 6 - Scala

With scala 2.13, there are two alternatives: the to method of the source map instance, or the from method of the destination map's companion object.

scala> import scala.collection.mutable
import scala.collection.mutable

scala> val immutable = Map(1 -> 'a', 2 -> 'b');
val immutable: scala.collection.immutable.Map[Int,Char] = Map(1 -> a, 2 -> b)

scala> val mutableMap1 = mutable.Map.from(immutable)
val mutableMap1: scala.collection.mutable.Map[Int,Char] = HashMap(1 -> a, 2 -> b)

scala> val mutableMap2 = immutable.to(mutable.Map)
val mutableMap2: scala.collection.mutable.Map[Int,Char] = HashMap(1 -> a, 2 -> b)

As you can see, the mutable.Map implementation was decided by the library. If you want to choose a particular implementation, for example mutable.HashMap, replace all occurrences of mutable.Map with mutable.HashMap.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionŁukasz LewView Question on Stackoverflow
Solution 1 - ScalaKevin WrightView Answer on Stackoverflow
Solution 2 - ScalaRex KerrView Answer on Stackoverflow
Solution 3 - ScalaXavier GuihotView Answer on Stackoverflow
Solution 4 - ScalaymnkView Answer on Stackoverflow
Solution 5 - ScalaAlexander AzarovView Answer on Stackoverflow
Solution 6 - ScalaReadrenView Answer on Stackoverflow