ฉันimmutable.Map
จะแปลงเป็นmutable.Map
ใน Scala เพื่อให้ฉันสามารถอัปเดตค่าในได้Map
อย่างไร
ฉันimmutable.Map
จะแปลงเป็นmutable.Map
ใน Scala เพื่อให้ฉันสามารถอัปเดตค่าในได้Map
อย่างไร
คำตอบ:
วิธีที่สะอาดที่สุดคือใช้mutable.Map
โรงงาน varargs ซึ่งแตกต่างจาก++
วิธีการนี้ใช้CanBuildFrom
กลไกและมีศักยภาพที่จะมีประสิทธิภาพมากขึ้นหากมีการเขียนโค้ดไลบรารีเพื่อใช้ประโยชน์จากสิ่งนี้:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
ใช้งานได้เนื่องจากMap
สามารถดูเป็นลำดับของคู่ได้
: _*
เหมือนกับคำอธิบายประเภทโดยบอกคอมไพเลอร์ว่าประเภทใดที่จะเทียบกับนิพจน์ที่กำหนด คุณสามารถคิดได้ที่นี่ว่า "รับลำดับนี้และถือว่ามันเป็นพารามิเตอร์ของวาราร์ก"
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
O(1)
ขั้นตอนต่างๆ นี้มีลักษณะที่จะO(n)
ถึงแม้ว่ามันจะขึ้นอยู่กับการเรียนการสอนเกี่ยวกับวิธีการที่ชาญฉลาดการดำเนินการ++
คือ
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")
วิธีการใช้ 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
ที่มีสำเร็จรูปมากขึ้นอีกนิด
มีความแตกต่างในการสร้างไม่แน่นอนที่ว่างเปล่าที่มีค่าเริ่มต้นที่นำมาจากไม่เปลี่ยนรูป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
Caveat (ดูความคิดเห็นของ Rex Kerr): คุณจะไม่สามารถลบองค์ประกอบที่มาจากแผนที่ที่ไม่เปลี่ยนรูปได้:
scala> mMap.remove(1)
//res5: Option[String] = None
scala> mMap(1)
//res6: String = one
ด้วย scala 2.13 มีสองทางเลือก: to
วิธีการของอินสแตนซ์แผนที่ต้นทางหรือfrom
วิธีการของวัตถุคู่หูของแผนที่ปลายทาง
scala> import scala.collection.mutable
import scala.collection.mutable
scala> val immutable = Map(1 -> 'a', 2 -> 'b');
val immutable: scala.collection.immutable.Map[Int,Char] = Map(1 -> a, 2 -> b)
scala> val mutableMap1 = mutable.Map.from(immutable)
val mutableMap1: scala.collection.mutable.Map[Int,Char] = HashMap(1 -> a, 2 -> b)
scala> val mutableMap2 = immutable.to(mutable.Map)
val mutableMap2: scala.collection.mutable.Map[Int,Char] = HashMap(1 -> a, 2 -> b)
อย่างที่คุณเห็นการmutable.Map
ใช้งานนั้นถูกกำหนดโดยไลบรารี หากคุณต้องการที่จะเลือกดำเนินการโดยเฉพาะอย่างยิ่งตัวอย่างเช่นmutable.HashMap
แทนที่เกิดขึ้นทั้งหมดด้วยmutable.Map
mutable.HashMap