Wie kann ich in Scala konvertieren immutable.Map, mutable.Mapum die Werte in zu aktualisieren Map?
Wie kann ich in Scala konvertieren immutable.Map, mutable.Mapum die Werte in zu aktualisieren Map?
Antworten:
Am saubersten wäre es, die mutable.MapVarargs-Fabrik zu benutzen . Im Gegensatz zum ++Ansatz verwendet dies den CanBuildFromMechanismus und kann daher effizienter sein, wenn Bibliothekscode geschrieben wurde, um dies auszunutzen:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
Dies funktioniert, weil a Mapauch als Folge von Paaren angesehen werden kann.
: _*ähnelt der Typzuweisung und teilt dem Compiler genau mit, welcher Typ einem bestimmten Ausdruck zugewiesen werden soll. Sie können sich das hier so vorstellen, dass Sie sagen: "Nehmen Sie diese Sequenz und behandeln Sie sie als eine Reihe von vararg-Parametern."
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
O(1). Dies scheint zu sein O(n), obwohl dies natürlich davon abhängt, wie clever die Implementierung ++ist.
O(n). Wenn Sie alles ändern, muss dies der Fall sein O(n). Sie können jedoch versuchen, die Erstellung der neuen Kopie zu verschieben, um Zeit zu sparen, oder Sie verdoppeln Ihre Zugriffszeiten, indem Sie Änderungssätze anstelle der ursprünglichen Karte lesen. Welche Leistung am besten erbracht wird, hängt wahrscheinlich von Ihrem Anwendungsfall ab.
Wie wäre es mit 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#applymit etwas mehr Boilerplate.
Starten Scala 2.13über Fabrikbauer angewendet mit .to(factory):
Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")
Es gibt eine Variante, um eine leere veränderbare Variable zu erstellen Map, deren Standardwerte von der unveränderlichen übernommen wurden Map. Sie können jederzeit einen Wert speichern und den Standardwert überschreiben:
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
Vorsichtsmaßnahme (siehe Kommentar von Rex Kerr): Sie können die Elemente aus der unveränderlichen Karte nicht entfernen:
scala> mMap.remove(1)
//res5: Option[String] = None
scala> mMap(1)
//res6: String = one