Assigning to an existing key
To change the value stored under a key, assign a new value to that key with the index operator. The old value is overwritten:
val scores = mutableMapOf("Alice" to 95, "Bob" to 87)
scores["Alice"] = 99
println(scores) // {Alice=99, Bob=87}
Only the value stored under "Alice" changes. Bob's entry stays as it was, and the map still has two entries. This works because the map is a MutableMap, created with mutableMapOf. A read-only map from mapOf has no assignment form, and scores["Alice"] = 99 on it does not compile.
One syntax for adding and updating
The same line of code both inserts and updates. If the key is not in the map yet, the assignment adds a new entry. If the key is there, it replaces the value:
scores["Charlie"] = 72 // new key: adds an entry
scores["Alice"] = 99 // existing key: replaces the value
println(scores) // {Alice=99, Bob=87, Charlie=72}
println(scores.size) // 3
That is convenient, but it also means a typo creates a new entry silently. If you write scores["Alise"] = 99, Kotlin does not complain. It adds an entry for "Alise" and leaves Alice's score alone. When an update must only touch an existing key, use the next function instead.
Updating only when the key exists
The function replace(key, value) changes the value only if the key is already in the map. It returns the previous value, or null if there was no such key, and in that case the map does not change:
println(scores.replace("Bob", 91)) // 87
println(scores.replace("Nobody", 5)) // null
println(scores.size) // 3
After these calls, Bob's score is 91, and nothing named "Nobody" was added.
The function put(key, value) also returns the previous value, and, unlike replace, it adds the entry if the key is missing. The index assignment is the same operation without the return value.
Updating based on the old value
A common update computes the new value from the old one, for example adding a point to a score. Read the value, calculate, and write it back:
scores["Bob"] = scores["Bob"]!! + 1
The right side reads Bob's current score with !!, which is safe only if the key exists. The sum is then stored under the same key. When the key may be missing, such as when counting how often something appears, give the lookup a default:
scores["Dana"] = (scores["Dana"] ?: 0) + 1
A missing "Dana" counts as 0, so the first update stores 1, and later updates add to it.
Updating several entries at once
The function putAll takes another map and applies each of its entries as if you had assigned them one by one. Existing keys get new values, and new keys are added:
val scores = mutableMapOf("Alice" to 95, "Bob" to 87)
scores.putAll(mapOf("Alice" to 1, "Eve" to 2))
println(scores) // {Alice=1, Bob=87, Eve=2}
Notice that Alice kept her place at the front. Updating a key changes its value, not its position in the map's order.
The exercise
The starting code has a map of two scores:
val scores = mutableMapOf("Alice" to 95, "Bob" to 87)
The task is to set Alice's score to 99. Below the map, assign to the "Alice" key:
val scores = mutableMapOf("Alice" to 95, "Bob" to 87)
scores["Alice"] = 99
Afterwards, the map is {Alice=99, Bob=87}. The variable is a val, and that is fine: the variable still refers to the same map, and only the map's contents change.
Common mistakes
- Re-declaring the map. Writing
val scores = mutableMapOf("Alice" to 99)a second time is an error, and even if it were allowed, it would drop Bob's entry. Update the existing map instead. - Misspelling the key. Keys are compared exactly, so
"alice"or"Alise"creates a new entry instead of updating"Alice". - Using a read-only map. A map from
mapOfcannot be assigned to. - Using a value of the wrong type. A
MutableMap<String, Int>accepts only integers, soscores["Alice"] = "99"does not compile.
Key takeaways
map[key] = valueadds the entry if the key is new and replaces the value if the key exists.replace(key, value)updates only existing keys and returns the old value ornull.- To change a value based on its old one, read it first, using
!!or?:, then write the result back.