2011-02-18 119 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也可以作爲一個序列的形式查看對。