java Kotlin中的for循环出现IndexOutOfBoundsException异常

pw136qt2  于 2022-12-02  发布在  Java
关注(0)|答案(3)|浏览(294)

在Kotlin中有两个大小相同的列表,foodObjects: MutableList<ParseObject>?checked: MutableList<Boolean>?,每次checked的元素为真时,我需要执行for循环,从foodObjects中获取objectId,在Java中是这样的:

for (int i = 0; i < foodObjects.size(); i++) {
    // here
}

但在Kotlin,我不知道为什么,出现了一些问题。事实上,如果我这样做:

for (i in 0..foodObjects!!.size) {
    if (checked?.get(i) == true) {
        objectsId?.add(foodObjects.get(i).objectId)
    }
}

我得到了IndexOutOfBoundsException。我不知道为什么,它也在foodObjects.size处继续循环。我也可以用filtermap来做:

(0..foodObjects!!.size)
    .filter { checked?.get(it) == true }
    .forEach { objectsId?.add(foodObjects.get(it).objectId) }

但是我得到了同样的错误。我用这个来停止错误并让它工作:

for (i in  0..foodObjects!!.size) {
    if (i < foodObjects.size) {
        if (checked?.get(i) == true) {
            objectsId?.add(foodObjects.get(i).objectId)
        }
    }
}

每个人都可以告诉我为什么在Kotlin我需要这样做,而在Java中它工作得很好?

zzzyeukh

zzzyeukh1#

Kotlin中的范围是包含的,因此0..foodObjects!!.size0开始,到foodObjects.size结束,包括两端。当循环试图用自己的大小索引列表时,这会导致异常,该大小比最大的有效索引大1。
要创建不包含上限的范围(如Java循环),可以使用until

for(i in 0 until foodObjects!!.size) {
    // ...
}

如果您在前面使用的集合上执行了空值检查,您也可以稍微清理一下代码:

if (foodObjects != null && checked != null && objectsId != null) {
    for (i in 0 until foodObjects.size) {
        if (checked.get(i) == true) {
            objectsId.add(foodObjects.get(i).objectId)
        }
    }
}
else {
    // handle the case when one of the lists is null
}

为了避免处理索引,可以使用列表的indices属性(另外,我在这里使用索引运算符,而不是get调用):

for (i in foodObjects.indices) {
    if (checked[i]) {
        objectsId.add(foodObjects[i].objectId)
    }
}

您也可以使用forEachIndexed

foodObjects.forEachIndexed { i, foodObject ->
    if (checked[i]) {
        objectsId.add(foodObject.objectId)
    }
}
hrysbysz

hrysbysz2#

看一下ranges的Kotlin文档中的示例:

if (i in 1..10) { // equivalent of 1 <= i && i <= 10
    println(i)
}

如你所见
第一、二、三、四、五、六、七、八、九、十
将被打印。因此,10被包括在内。
集合foodObjects的最高索引是(foodObjects.size() - 1),因为它从0开始。
因此,要解决您的问题,只需执行以下操作:

for(i in  0..(foodObjects.size - 1)) { 
   // ...
}

更好的写法是:

for((i, element) in foodObjects.withIndex()){
   // do something with element
   println("The index is $i")
}

这样,您就可以同时拥有元素和索引,而不必担心范围。

  • 为了简单起见,我删除了空检查。
vu8f3i0k

vu8f3i0k3#

以下是确保索引有效的各种方法:
第一个问题

相关问题