Яким чином можна перетворити immutable.Map
в mutable.Map
в Scala , так що я можу оновити значення в Map
?
Відповіді:
Найчистішим способом було б використання mutable.Map
фабрики вараргів. На відміну від ++
підходу, тут використовується CanBuildFrom
механізм, і тому потенціал може бути більш ефективним, якщо бібліотечний код був написаний, щоб скористатися цим:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
Це працює, оскільки a Map
також можна розглядати як послідовність пар.
: _*
нагадує атрибуцію типу, повідомляючи компілятору, який саме тип призначати даному виразу. Тут ви можете думати про це як про те, що "прийміть цю послідовність і поводьтеся з нею як безліч параметрів vararg".
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
O(1)
поетапно. Це виглядає бути O(n)
, хоча це залежить, звичайно , від того, наскільки розумний реалізації ++
ІС.
O(n)
. Коли ви змінюєте все, це має бути O(n)
, хоча ви можете спробувати відкласти створення нової копії, щоб заощадити час, або подвоїти час доступу, прочитавши набори змін замість оригінальної карти. Який із них буде найкращим, можливо, залежить від вашого варіанту використання.
Як щодо використання 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
з трохи більше шаблоннога.
Починаючи Scala 2.13
від будівельників заводів, які застосовуються з .to(factory)
:
Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")
Існує варіант створення порожньої змінної, Map
яка має значення за замовчуванням, взяті з незмінного Map
. Ви можете будь-коли зберегти значення та замінити значення за замовчуванням:
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
Застереження (див. Коментар Рекса Керра): Ви не зможете видалити елементи, що надходять із незмінної карти:
scala> mMap.remove(1)
//res5: Option[String] = None
scala> mMap(1)
//res6: String = one