Home > Blockchain >  MutableList of MutableLists in Kotlin: adding element error
MutableList of MutableLists in Kotlin: adding element error

Time:12-10

Why I'm getting "java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0" while running next code??? :

val totalList = mutableListOf<MutableList<Int>>()

fun main() {
    for (i in 0..15) {
        for (j in 0..10) {
            *some operations and calculations with **var element of type Int***
            totalList[i].add(element)
        }
    }
}

I was thinking that in such case while iterating through 'j' it should add elements to mutableList[i], after this it should start adding elements to mutableList[i 1] etc.... But instead I am recieving IndexOutOfBoundsException....

CodePudding user response:

val totalList = mutableListOf<MutableList<Int>>()

All this does is create one list which is going to contain MutableList<Int> items. Right now, there's nothing in it (you've supplied no initial elements in the parentheses).

Skip forward a bit, and you do this:

totalList[0].add(element)

You're trying to get the first element of that empty list and add to it. But there is no first element (index 0) because the list is empty (length 0). That's what the error is telling you.

There's lots of ways to handle this - one thing you could do is create your lists up-front:

// create the 16 list items you want to access in the loop
// (the number is the item count, the lambda generates each item)
val totalList = MutableList(16) { mutableListOf<Int>() }

// then refer to that list's properties in your loop (no hardcoded 0..15)
for (i in totalList.indices) {
    ...
    // guaranteed to exist since i is generated from the list's indices
    totalList[i].add(element)
}

Or you could do it the way you are now, only using getOrElse to generate the empty list on-demand, when you try to get it but it doesn't exist:

for (i in 0..15) {
    for (j in 0..10) {
        // if the element at i doesn't exist, create a list instead, but also
        // add it to the main list (see below)
        totalList.getOrElse(i) {
            mutableListOf<Int>().also { totalList.add(it) }
        }.add(element)
    }
}

Personally I don't really like this, you're using explicit indices but you're adding new list items to the end of the main list. That implicity requires that you're iterating over the list items in order - which you are here, but there's nothing enforcing that. If the order ever changed, it would break.

I'd prefer the first approach - create your structure of lists in advance, then iterate over those and fill them as necessary. Or you might want to consider arrays instead, since you have a fixed collection size you're "completing" by adding items to specific indices

  • Related