Kotlin中for循环的IndexOutOfBoundsException

ste*_*206 1 java list arraylist indexoutofboundsexception kotlin

我有两个列表科特林,同样大小的,foodObjects: MutableList<ParseObject>?checked: MutableList<Boolean>?.我需要做一个for循环并从foodObjects每次元素checked为true 时获取objectId .所以在Java中就是这样:

  for(int i = 0; i< foodObjects.size(); i++) {
      //here
  }
Run Code Online (Sandbox Code Playgroud)

但是在Kotlin,我不知道为什么,有一些问题.事实上,如果我这样做:

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

 }
Run Code Online (Sandbox Code Playgroud)

我有IndexOutOfBoundsException:我不知道为什么,它继续循环也在foodObjects.size.我也可以使用过滤器和地图来做到这一点:

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

但我给出了同样的错误.如果出现以下情况,我需要停止使用它:

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

让它工作.

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

zsm*_*b13 11

Kotlin的范围是包容性的,因此0..foodObjects!!.size从包括两端开始0foodObjects.size结束.当您的循环尝试使用自己的大小索引列表时,这会导致异常,该大小比最大的有效索引多一个.

要创建不包含上限的范围(如Java循环),您可以使用until:

for(i in 0 until foodObjects!!.size) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果您对预先使用的集合进行空检查,您还可以清理一下代码:

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
}
Run Code Online (Sandbox Code Playgroud)

为了摆脱必须完全处理索引,你可以使用indices列表的属性(加上我在这里使用索引操作符而不是get调用):

for (i in foodObjects.indices) {
    if (checked[i]) {
        objectsId.add(foodObjects[i].objectId)
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以使用forEachIndexed:

foodObjects.forEachIndexed { i, foodObject ->
    if (checked[i]) {
        objectsId.add(foodObject.objectId)
    }
}
Run Code Online (Sandbox Code Playgroud)