为什么下面的代码抛出ConcurrentModificationException? Josh Bloch可以避免ConcurrentModificationException。
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(100);
list.add(200);
list.add(300);
list.add(400);
for(Integer field : list) {
list.remove(field);
list.add(200);
}
答案 0 :(得分:5)
使用“for each”循环时,不能在列表中使用remove。相反,您可以使用它在迭代器上调用remove:
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
Integer integer = iterator.next();
// ...check if you want to remove this one...
iterator.remove();
}
如果您确实想要用“200”替换每个值,或者替换为其他值,那么构建新列表可能更有意义:
List<Integer> newList = new ArrayList<Integer>();
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
Integer integer = iterator.next();
newList.add(integer);
iterator.remove();
}
答案 1 :(得分:3)
如果您在修改数组时迭代数组,那么行为应该是什么不清楚。
如果删除一个元素,如果它仍然被迭代怎么办?
该列表不会尝试猜测,而是抛出ConcurrentModificationException以导致错误,而不是通过意外行为传递。
一种解决方案是您可以迭代列表的浅表副本,然后修改原始列表
答案 2 :(得分:0)
您可以从正在使用的ArrayList中删除对象。我在我的游戏引擎中使用它,它可以工作。
请参阅http://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/map/Map.java#350
for (int i = 0; i < objects.size(); i++) {
GObject other = objects.get(i);
if (other.isAlive()) {
// Update it
} else {
// Else remove it
objects.remove(i);
}
}
您遇到的错误是这对for each
循环不起作用。尝试正常的for
循环,这应该可以解决您的问题。
将您的代码更改为此。
ArrayList<Integer> list =new ArrayList<Integer>();
ArrayList<Integer> remove = new ArrayList<Integer>();
list.add(100);
list.add(200);
list.add(300);
list.add(400);
// Mark to remove
for (int i=0; i<list.size(); i++){
remove.add(list.get(i));
}
list.removeAll(remove);
remove.clear();
// adding 200 at the end because if added in the loop,
// it removes the 200 and adds every loop which causes
// unnecessary memory usage.
list.add(200);