Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
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?
The statement map.getValue(num) += 1
is not allowed because the +=
operator is only defined in 2 cases:
a plusAssign() operator is defined on the left operand's type (not the case for Int
)
a plus() operator is defined on the left operand's type AND the left operand is a variable. In this case +=
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:
if the key doesn't exist in the map, it just sets the value given as second argument (the value 1)
if the key already exists, then a new value is computed using the function given as 3rd argument (just a sum). That function is called with the old value and the 2nd argument (the value 1) as inputs, and should return the new value to assign, so in this case 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()
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.