Comment puis - je convertir immutable.Map
à mutable.Map
Scala afin que je puisse mettre à jour les valeurs Map
?
Comment puis - je convertir immutable.Map
à mutable.Map
Scala afin que je puisse mettre à jour les valeurs Map
?
Réponses:
Le moyen le plus propre serait d'utiliser l' mutable.Map
usine varargs. Contrairement à l' ++
approche, cela utilise le CanBuildFrom
mécanisme, et a donc le potentiel d'être plus efficace si le code de la bibliothèque a été écrit pour en tirer parti:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
Cela fonctionne car a Map
peut également être considéré comme une séquence de paires.
: _*
est un peu comme l'attribution de type, indiquant au compilateur exactement quel type attribuer à une expression donnée. Vous pouvez le considérer ici comme disant "prenez cette séquence et traitez-la comme un certain nombre de paramètres vararg".
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
O(1)
étapes. Cela semble être le cas O(n)
, bien que cela dépende bien sûr de l'intelligence de la mise en œuvre ++
.
O(n)
. Dans la limite lorsque vous modifiez tout, cela doit être O(n)
, bien que vous puissiez essayer de différer la création de la nouvelle copie pour gagner du temps, ou vous doublez vos temps d'accès en lisant les changesets au lieu de la carte d'origine. Celui qui fonctionne le mieux dépend probablement de votre cas d'utilisation.
Que diriez-vous d'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)
mutable.Map#apply
d'un peu plus passe- partout.
Démarrage Scala 2.13
, via les constructeurs d'usine appliqué 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 un mutable vide Map
dont les valeurs par défaut sont extraites de l'immuable Map
. 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
Attention (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