迭代时从列表中移除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 } }