2011-02-18 51 views

回答

29
val myImmutableMap = collection.immutable.Map(1->"one",2->"two") 
val myMutableMap = collection.mutable.Map() ++ myImmutableMap 
+0

你知道这是什么时候的渐近时间复杂吗?我知道Clojure可以将它的任何持久化集合变成一个“瞬态”集合(即一个具有线性类型变异函数的可变集合),并在'O(1)'步骤中变回一个持久集合。这*看起来是'O(n)`,尽管这当然取决于'++'的实现有多聪明。 – 2011-02-18 15:34:45

+0

@Jörg - 我很确定这个是'O(n)`。尽管您可以尝试延迟新副本的创建以节省时间,但您可以通过读取变更集而不是原始映射来将访问时间加倍,但在改变所有内容的限制内,它必须是“O(n)”。哪一个表现最好取决于你的用例。 – 2011-02-18 16:00:58

+1

@Rustem - 地图无序。它们将以他们感觉的顺序出现(使用哈希映射,通常是哈希键的顺序)。特别是,不可变映射对于与可变映射不同的非常小的映射有特殊情况。 – 2011-02-18 16:47:07

3

如何使用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

还有就是要创建一个空的可变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 
92

最简洁的方法是使用mutable.Map可变参数工厂。不像++方法,这里使用了CanBuildFrom机制,因此有潜力成为更有效的,如果库代码被写入利用这一点:

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

这工作,因为一个Map也可以作为一个序列的形式查看对。

相关问题