Why ConcurrentModificationException in ArrayList? [duplicate]

感情迁移 提交于 2019-12-20 04:46:58

问题


why following code throwing ConcurrentModificationException? Josh Bloch can avoid 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);
}       

回答1:


You can't use remove on the list while using the "for each" loop. Instead, you can use this to call remove on the iterator:

Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
    Integer integer = iterator.next();

    // ...check if you want to remove this one...

    iterator.remove();
}

If you actually want to replace every value with "200", or replace with some other value, it might make more sense to build up a new list:

List<Integer> newList = new ArrayList<Integer>();

Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
    Integer integer = iterator.next();

    newList.add(integer);

    iterator.remove();
}



回答2:


It's unclear what the behavior should be if you're iterating over an array while modifying it.

What if you remove an element, should it still be iterated over?

Rather than trying to guess, the list throws a ConcurrentModificationException to cause an error rather than pass with unexpected behavior.

One solution is that you could iterate over a shallow copy of the list, and then modify the original list




回答3:


You can remove objects from the ArrayList which you are using. I use this in my game engine and it works.

See 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);
    }
}

What the error you are having is this does not work for the for each loop. Try in a normal for loop and that should solve your problem.

Change your code to this.

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);


来源:https://stackoverflow.com/questions/12793199/why-concurrentmodificationexception-in-arraylist

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!