2017-07-26 117 views
0

我有两个列表Kotlin,相同大小foodObjects: MutableList<ParseObject>?checked: MutableList<Boolean>?。每当checked的元素成立时,我需要做一个for循环,并从foodObjects中获取objectId。所以这是在Java中:IndexOutOfBoundsException for循环在Kotlin

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。我也可以用过滤器和地图来做:

(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中它工作的很好?

回答

9

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

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

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

您还可以清理你的代码了一下,如果你做了你正在使用前面的集合null检查:

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) 
    } 
} 
+0

谢谢,我以为它和Java很相似,现在我明白了! – ste9206

+0

对不起我的问题,但如何在recyclerview中使用此结构?我发现了同样的问题 – ste9206

+0

我不确定你的问题是关于RecyclerView的,但你应该将它作为一个新问题发布。 – zsmb13

1

看看从科特林文档这个例子ranges

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

由于你可以看到

1,2,3,4,5,6,7,8,9,10

将被打印。所以,包括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") 
} 

这种方式,你有元素和索引一次,不需要担心范围。

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