If I have an immutableMap: Map<String, Int>
and want to convert it to a mutableMap: MutableMap<String, Int>
, what would be the best way to do that? There doesn't seem like any convenient way.
If you want the result to be of read-only type, declare the type manually or use a cast: val copy : Map<Int,String> = HashMap(original) or val copy = HashMap(original) as Map<Int, String> . If you do this repeatedly, write an extension function.
To add a new key-value pair to a mutable map, use put() . When a new entry is put into a LinkedHashMap (the default map implementation), it is added so that it comes last when iterating the map. In sorted maps, the positions of new elements are defined by the order of their keys.
In Kotlin, key/value pairs are called entries. It is important to note that Kotlin maps are immutable by default. This means that entries cannot be edited, deleted, or changed in any way after they have been created.
Kotlin Map : mapOf() Kotlin distinguishes between immutable and mutable maps. Immutable maps created with mapOf() means these are read-only and mutable maps created with mutableMapOf() means we can perform read and write both. The first value of the pair is the key and the second is the value of the corresponding key.
Update: The Kotlin 1.1 stdlib has a .toMutableMap()
function. This should be used instead of creating your own.
----------------------- Old Answer Below ------------------------------
The following extension function works by copying the Map
to a MutableMap
.
fun <K, V> Map<K, V>.toMutableMap(): MutableMap<K, V> {
return HashMap(this)
}
Some of the other answers suggest checking to see if the map is a MutableMap
and then casting to it if it is. This should be avoided at all costs, as it's a bad practice. The fact that it was downcasted to a Map
in Kotlin implies that it's expected that this Map
shouldn't be changed, and it would be dangerous to do so.
First, as covered in previous questions about Kotlin read only collections and their immutability, they are really read only live views of likely mutable collections.
Kotlin CAN safely check the type for mutability for these since there are markers on the interfaces that let Kotlin know, for example:
// assuming some variable readOnlyMap of type Map<String, String>
val mutableMap: MutableMap<String, String> = if (readOnlyMap is MutableMap<*,*>) {
readOnlyMap as MutableMap
} else {
HashMap(readOnlyMap)
}
This is
check internally calls TypeIntrinsics.isMutableMap
and is a valid way to know if it is castable. There is no danger in the cast if you do this check first. You'll note the compiler is perfectly happy and without warnings. This could be dangerous if you don't intend to modify the same map being treated as read-only, but shows that you can cast for affect.
If you do not want the chance of modifying your original map, then of course always make a copy by simply calling constructor of HashMap with another Map, HashMap(readOnlyMap)
. Or make an extension function:
fun <K, V> Map<K, V>.toMutableCopy() = HashMap(this)
and call it:
val mutableMap = readOnlyMap.toMutableCopy()
And now you have your simple way.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With