在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
处继续循环。我也可以用filter
和map
来做:
(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中它工作得很好?
3条答案
按热度按时间zzzyeukh1#
Kotlin中的范围是包含的,因此
0..foodObjects!!.size
从0
开始,到foodObjects.size
结束,包括两端。当循环试图用自己的大小索引列表时,这会导致异常,该大小比最大的有效索引大1。要创建不包含上限的范围(如Java循环),可以使用
until
:如果您在前面使用的集合上执行了空值检查,您也可以稍微清理一下代码:
为了避免处理索引,可以使用列表的
indices
属性(另外,我在这里使用索引运算符,而不是get
调用):您也可以使用
forEachIndexed
:hrysbysz2#
看一下ranges的Kotlin文档中的示例:
如你所见
第一、二、三、四、五、六、七、八、九、十
将被打印。因此,10被包括在内。
集合
foodObjects
的最高索引是(foodObjects.size() - 1)
,因为它从0开始。因此,要解决您的问题,只需执行以下操作:
更好的写法是:
这样,您就可以同时拥有元素和索引,而不必担心范围。
vu8f3i0k3#
以下是确保索引有效的各种方法:
第一个问题