Reputation: 23
val bucket = mutableMapOf<String, MutableSet<String>>()
I insert multiple keys in bucket. My logic is here
for(temp in report_unique){
val str = temp.split(" ")//str example = "a b"
if(bucket.containsKey(str[0]))
bucket[str[0]]?.add(str[1])
else{
val t = mutableSetOf<String>()
bucket[str[0]]? = t // runtime error
bucket[str[0]]?.add(str[1])
}
I don`t know why the error occured, and want to know right answer. So Hard Kotlin null checking.
Upvotes: 0
Views: 316
Reputation: 37710
EDIT: since you clarified in the comments with more information and your actual code doesn't use the problematic ?
, the problem is a bit clearer:
ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
This error tells you that you're trying to access index 0 in str
, and it's out of bounds because str
is of length 0 (it has 0 elements). By accessing index 0, you're assuming that str contains at least 1 element, but it's apparently not the case.
You should look at what temp
contains. If temp == ""
, split
will return an empty list, and you'll see this error.
I think you're mistaken and you don't have a runtime error but a compile error. Trying your code on the Kotlin playground, I got the following compile error:
Unexpected tokens (use ';' to separate expressions on the same line)
This is because the syntax of bucket[str[0]]? = t
is invalid, you have an extra ?
. Let's break it down.
The basic function to insert into a map is put
, as in map.put(key, value)
. On top of that, Kotlin provides a convenient set
operator that allows you to use the square bracket syntax. So when you write map[key] = value
, it's translated into map.set(key, value)
.
The syntax for this specific operator doesn't support any ?
here, and it's not even necessary in your case anyway, as you could simply write:
bucket[str[0]] = t
The map is not null, and here you're not trying to use a null value, you're assigning a non-null value to a key in the map, so there is no need to use any safe operator (?
).
Now that this is out of the way, note that you can the whole if
with the help of computeIfAbsent
:
for(temp in report_unique){
val str = temp.split(" ")//str example = "a b"
bucket.computeIfAbsent(str[0]) { mutableSetOf<String>() }.add(str[1])
}
You could even replace the whole thing by creating the bucket
map directly using groupBy
:
val bucket = report_unique.groupBy({ it.substringBefore(" ") }, { it.substringAfter(" ")})
Upvotes: 1