迭代时从列表中移除IndexOutOfBoundsException:Java-> Kotlin

该代码在Java中工作,但转换为Kotlin时,它不再有效。 它抛出一个IndexOutOfBoundsException

这是原来的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); } } } }); 

这是新的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) } } } 

由于indices是初次初始化的,所以在从List移除元素之后, forEach操作的indices永远不会改变,但是size()会在Java中改变,例如:

 // v--- `size` is changed after remove item from List for (int j = 0; j < itemList.size(); j++){ //... } 

对于Kotlin中的可变操作,请使用MutableCollection#removeIf / MutableCollection#removeAll代替,例如:

 itemList.removeIf { it == selectedItem } // java-8 itemList.removeAll { it == selectedItem } // Kotlin 

并且 Java代码有一个错误的逻辑,例如:

 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 } }