Answers:
最干净的方法是使用mutable.Map
varargs工厂。与这种++
方法不同,它使用了该CanBuildFrom
机制,因此如果编写库代码来利用此机制,则有可能变得更加高效:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
之所以Map
可行,是因为a 也可以视为成对的序列。
: _*
与类型归属非常相似,它告诉编译器将哪种类型分配给给定的表达式。您可以在这里将其视为“采用此序列,并将其视为许多vararg参数”。
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
O(1)
逐步转换为持久性集合。这看起来是O(n)
,尽管在如何巧妙的实现,当然取决于++
IS。
O(n)
。在更改所有内容的限制中,它必须为O(n)
,尽管您可以尝试推迟创建新副本以节省时间,或者通过读取更改集而不是原始映射来使访问时间加倍。哪一个性能最好取决于您的用例。
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
警告(请参阅Rex Kerr的评论):您将无法删除来自不变地图的元素:
scala> mMap.remove(1)
//res5: Option[String] = None
scala> mMap(1)
//res6: String = one