[英]IndexOutOfBoundsException for for-loop in Kotlin
我在 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 中效果如何?
Kotlin中的范圍是包含范圍的,因此0..foodObjects!!.size
始於0
,結束於foodObjects.size
,包括兩端。 當您的循環嘗試使用自己的大小索引列表時,這會導致異常,該大小比最大有效索引大一。
要創建不包含上限的范圍(如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)
}
}
查看Kotlin文檔中有關范圍的以下示例:
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")
}
這樣,您就可以一次擁有元素和索引,而不必擔心范圍。
*為簡單起見,我刪除了空檢查。
以下是確保索引有效的各種方法:
if (index in myList.indices) {
// index is valid
}
// The rangeUntil operator (..<) is still exprimental in Kotlin 1.7.20
if (index in 0..<myList.size) {
// index is valid
}
if (index in 0 until myList.size) {
// index is valid
}
if (index in 0..myList.lastIndex) {
// index is valid
}
if (index >= 0 && index <= myList.lastIndex) {
// index is valid
}
// Note: elements of the list should be non-null
if (myList.getOrNull(index) != null) {
// index is valid
}
// Note: elements of the list should be non-null
myList.getOrNull(index)?.let { element ->
// index is valid; use the element
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.