Comment puis - je convertir immutable.Mapà mutable.MapScala afin que je puisse mettre à jour les valeurs Map?
Comment puis - je convertir immutable.Mapà mutable.MapScala afin que je puisse mettre à jour les valeurs Map?
Réponses:
Le moyen le plus propre serait d'utiliser l' mutable.Mapusine varargs. Contrairement à l' ++approche, cela utilise le CanBuildFrommé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 Mappeut é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#applyd'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 Mapdont 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