Reputation: 71
the code worked in Java but when converted to Kotlin it is no longer works. It throws an IndexOutOfBoundsException
.
Here is the original Java:
grid_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String selectedItem = ((TextView) view.findViewById(R.id.tag_name)).getText().toString();
for (int j = 0; j < itemList.size(); j++){
String tempString = itemList.get(j);
if(tempString.equals(selectedItem)) {
Log.d("Update", "Removing: " + selectedItem);
itemList.remove(j);
}
}
}
});
Here is the new Kotlin:
grid_view!!.onItemClickListener = AdapterView.OnItemClickListener { _, _, _, _ ->
val selectedItem = (tag_name as TextView).text.toString()
itemList.indices.forEach {
val tempString = itemList[it]
if (tempString == selectedItem) {
Log.d("Update", "Removing: " + selectedItem)
itemList.removeAt(it)
}
}
}
Upvotes: 1
Views: 1638
Reputation: 30686
Since indices
is initialized at the first time, so the indices
of the forEach
operation is never changed after you remove element from a List
, but size()
is changed in Java, for example:
// v--- `size` is changed after remove item from List
for (int j = 0; j < itemList.size(); j++){
//...
}
For the mutable operation in Kotlin, please using MutableCollection#removeIf / MutableCollection#removeAll instead, for example:
itemList.removeIf { it == selectedItem } // java-8
itemList.removeAll { it == selectedItem } // Kotlin
AND there is a wrong logic of your Java code, for example:
for (int j = 0; j < itemList.size(); j++){
String tempString = itemList.get(j);
if(tempString.equals(selectedItem)) {
itemList.remove(j--);
// ^
// you should minus the current j, if don't the next is skipped
}
}
Upvotes: 3