Roc47HS
Roc47HS

Reputation: 71

Removing from list throws IndexOutOfBoundsException while iterating: Java->Kotlin

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

Answers (1)

holi-java
holi-java

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

Related Questions