Bagaimana cara mengonversi immutable.Map
ke mutable.Map
dalam Scala sehingga saya dapat memperbarui nilai di Map
?
Bagaimana cara mengonversi immutable.Map
ke mutable.Map
dalam Scala sehingga saya dapat memperbarui nilai di Map
?
Jawaban:
Cara terbersih adalah dengan menggunakan mutable.Map
pabrik varargs. Berbeda dengan ++
pendekatan, ini menggunakan CanBuildFrom
mekanisme, dan berpotensi menjadi lebih efisien jika kode perpustakaan ditulis untuk memanfaatkan ini:
val m = collection.immutable.Map(1->"one",2->"Two")
val n = collection.mutable.Map(m.toSeq: _*)
Ini berfungsi karena a Map
juga dapat dilihat sebagai urutan Pasangan.
: _*
sangat mirip dengan tipe ascription, yang memberi tahu kompiler tipe apa yang harus ditambahkan ke ekspresi yang diberikan. Anda dapat menganggapnya di sini seperti mengatakan "ambillah urutan ini, dan perlakukan itu sebagai sejumlah parameter vararg".
val myImmutableMap = collection.immutable.Map(1->"one",2->"two")
val myMutableMap = collection.mutable.Map() ++ myImmutableMap
O(1)
langkah. Ini terlihat menjadi O(n)
, walaupun itu tentu saja tergantung pada seberapa pintar pelaksanaan ++
yaitu.
O(n)
. Dalam batas saat Anda mengubah segalanya, itu harus O(n)
, meskipun Anda dapat mencoba untuk menunda pembuatan salinan baru untuk menghemat waktu, atau Anda menggandakan waktu akses Anda dengan membaca set perubahan daripada peta asli. Mana yang berkinerja terbaik mungkin tergantung pada kasus penggunaan Anda.
Bagaimana kalau menggunakan 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
dengan sedikit lebih boilerplate.
Memulai Scala 2.13
, melalui pembangun pabrik yang diterapkan dengan .to(factory)
:
Map(1 -> "a", 2 -> "b").to(collection.mutable.Map)
// collection.mutable.Map[Int,String] = HashMap(1 -> "a", 2 -> "b")
Ada varian untuk membuat bisa berubah kosong Map
yang memiliki nilai default yang diambil dari yang tidak bisa diubah Map
. Anda dapat menyimpan nilai dan mengganti default kapan saja:
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
Peringatan (lihat komentar oleh Rex Kerr): Anda tidak akan dapat menghapus elemen yang berasal dari peta yang tidak dapat diubah:
scala> mMap.remove(1)
//res5: Option[String] = None
scala> mMap(1)
//res6: String = one