Как я могу преобразовать immutable.Map в mutable.Map в Scala? - PullRequest
81 голосов
/ 18 февраля 2011

Как я могу преобразовать immutable.Map в mutable.Map в Scala, чтобы я мог обновить значения в Map?

Ответы [ 5 ]

114 голосов
/ 19 февраля 2011

Самый простой способ - использовать фабрику mutable.Map varargs. В отличие от подхода ++, здесь используется механизм CanBuildFrom, и поэтому он может быть более эффективным, если код библиотеки был написан для использования этого преимущества:

val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*) 

Это работает, потому что Map также можно рассматривать как последовательность пар.

39 голосов
/ 18 февраля 2011
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
4 голосов
/ 18 февраля 2011

Как насчет использования 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)
0 голосов
/ 30 июня 2019

Начиная с Scala 2.13, через заводских строителей, применяемых с .to(factory):

Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")
0 голосов
/ 18 февраля 2011

Существует вариант создания пустой изменяемой переменной 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
...