Reputation: 1026
I'm having a problem with altering the value of a mutable map. I assume it's something to do with nullable types, but I'm not sure. The code producing the error is below:
fun countHexadecimalNumbers(codes: List<String>): Map<Int, Int> {
val map = mutableMapOf<Int, Int>()
for (s in codes) {
val num = s.toIntOrNull(16)
if (num != null) {
if (num !in map.keys) {
map[num] = 0
}
map.getValue(num) += 1 %<--This line causes the issue
}
}
return map
When I try and build the code I get this error:
Nullable Types\Exercise 3\src\Task.kt: (13, 11): Variable expected
Does anyone have any idea why this isn't allowed?
Upvotes: 1
Views: 929
Reputation: 37680
The statement map.getValue(num) += 1
is not allowed because the +=
operator is only defined in 2 cases:
Int
)+=
reassigns the variable on the left with oldValue.plus(the right operand)
.The compiler tries to consider case #2 here because Int.plus(Int)
is defined, but the left operand is not a variable so it fails with the error message you mentioned.
You can't write this for the same reasons you can't write map.getValue(num) = 42
.
The correct way of mutating a value in a map is either via the set operator (like you did earlier with the syntax sugar map[num] = 0
), or via other mutating functions like merge.
In your case, merge
is nice because it can remove the special case altogether (it's only available on the JVM target though):
val map = mutableMapOf<Int, Int>()
for (s in codes) {
val num = s.toIntOrNull(16)
if (num != null) {
map.merge(num, 1, Int::plus)
}
}
Here is what this merge
does:
old + 1
.Note that, in your case, the whole loop can be simplified this way:
fun countHexadecimalNumbers(codes: List<String>): Map<Int, Int> {
return codes.mapNotNull { it.toIntOrNull(16) }.groupingBy { it }.eachCount()
}
Upvotes: 2