I found that IntelliJ asks me to add an only safe ...
# getting-started
v
I found that IntelliJ asks me to add an only safe call to the value of an entry of a Map although I first verify that it is non-null
val mutableMap<String, mutableSet<String>> myMap = mutableMapOf ("first key" to mutableSetOf("value1 of first entry","value2 of first entry"))
if (myMap["another key"]==null)
myMap["another key"] = mutableSetOf("value1 of second entry")
else
//at this point, we know that myMap["another key"] is NOT NULL
myMap["another key"].add("value1 of second entry")
It marks the last line (marked in bold) and says that I should use ?. instead of . because it says the receiver of the call is of type
MutableSet<String>?
(nullable) but it is verified that it is not. Am I missing something?
m
Think multi-threading environment. No guarantee another thread hasn't removed it by the time you get there. I think you want
Copy code
myMap.getOrPut("another key", { mutableSetOf() }).add("value 1 of second entry")
😃 1
v
Ok, got the idea. And the example you gave is much better and it covers what I was trying to do, thanks!
👍 1
Just in case anyone tries your solution, after I tried it, be careful that the second parameter of
.getOrPut()
is a lambda, so it must go between
{}
, as well as expressing the type of the content inside the MutableSet. So, in this example: [CHANGES DONE MARKED IN BOLD]
myMap.getOrPut("another key", *{* mutableSetOf~*<String>*~() *}* ).add("value 1 of second entry")
(Mike was good at his solution in the way that
getOrPut()
returns the value of the entry, even if it is the one entry just created because it didn't exist previously). 2019-11-26 EDIT: the
<String>
part is not needed, the Kotlin type inference engine (on actual release version) is able to run it. It is more simple this way, only adding the
{}
that were missing on the first version wrote by Mike, as it is a lamba function. =)
m
Ahh, yes, forgot to update that. I'll edit my original. Thanks.
v
And the
<String>
is missing. Kotlin didn't seem to infer it.
2019-11-26 EDIT: Not needed, I should had another typo error when I tried it.
m
Hmm. Should have copied directly from my scratch file, although I seem.to recall mine was able to. Perhaps different versions of Kotlin as I know the inference engine has improved. I'll look when I'm back at keyboard.
Using 1.3.50, and the following compiles as expected:
Copy code
val test = mutableMapOf<String, MutableSet<String>>()

test.getOrPut("value", { mutableSetOf() }).add("valueentry")
Are you using 1.3.41 or earlier?
v
Tried again. Now it worked without the
<String>
... Sorry for that :'). Runing 1.3.60. Edited my prior message to avoid confusion for future readers of this thread.
m
I updated my original after it's comment, so it's correct too. And no worries, we all upgrade at different paces, and Kotlin keeps evolving.
v
😁👍 (yep, I saw your edit, just corrected mine to avoid confusion) Glad for being here