Calling remove in foreach loop in Java [duplicate] Calling remove in foreach loop in Java [duplicate] java java

Calling remove in foreach loop in Java [duplicate]


To safely remove from a collection while iterating over it you should use an Iterator.

For example:

List<String> names = ....Iterator<String> i = names.iterator();while (i.hasNext()) {   String s = i.next(); // must be called before you can call i.remove()   // Do something   i.remove();}

From the Java Documentation :

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Perhaps what is unclear to many novices is the fact that iterating over a list using the for/foreach constructs implicitly creates an iterator which is necessarily inaccessible. This info can be found here


You don't want to do that. It can cause undefined behavior depending on the collection. You want to use an Iterator directly. Although the for each construct is syntactic sugar and is really using an iterator, it hides it from your code so you can't access it to call Iterator.remove.

The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.

Instead write your code:

List<String> names = ....Iterator<String> it = names.iterator();while (it.hasNext()) {    String name = it.next();    // Do something    it.remove();}

Note that the code calls Iterator.remove, not List.remove.

Addendum:

Even if you are removing an element that has not been iterated over yet, you still don't want to modify the collection and then use the Iterator. It might modify the collection in a way that is surprising and affects future operations on the Iterator.


for (String name : new ArrayList<String>(names)) {    // Do something    names.remove(nameToRemove);}

You clone the list names and iterate through the clone while you remove from the original list. A bit cleaner than the top answer.