1

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);
}       
Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91

3 Answers3

5

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();
}
Cory Kendall
  • 7,195
  • 8
  • 37
  • 64
3

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

Will
  • 1,622
  • 4
  • 25
  • 39
0

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);
Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91