Comment convertir immutable.Map en mutable.Map dans Scala afin de pouvoir mettre à jour les valeurs dans Map?
Le moyen le plus propre serait d’utiliser l’usine mutable.Map
varargs. Contrairement à l'approche ++
, cette méthode utilise le mécanisme CanBuildFrom
et a donc le potentiel d'être plus efficace si le code de la bibliothèque était écrit pour tirer parti de ceci:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
Cela fonctionne car une Map
peut également être vue comme une séquence de paires.
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
Pourquoi ne pas utiliser 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)
Démarrer Scala 2.13
, via les constructeurs d’usine appliqués avec .to(factory)
:
Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")
Il existe une variante pour créer une variable Map
mutable vide dont les valeurs par défaut sont extraites de la variable Map
immuable. Vous pouvez stocker une valeur et remplacer la valeur par défaut à tout moment:
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
Avertissement (voir le commentaire de Rex Kerr): Vous ne pourrez pas supprimer les éléments provenant de la carte immuable:
scala> mMap.remove(1)
//res5: Option[String] = None
scala> mMap(1)
//res6: String = one