loop on list with remove

Viewed 48252
    for (String fruit : list)
    {
        if("banane".equals(fruit))
            list.remove(fruit);
        System.out.println(fruit);
    }

Here a loop with remove instruction. At execution time, I get some ConcurrentModificationException, below the console output:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
at java.util.AbstractList$Itr.next(AbstractList.java:420)
at Boucle.main(Boucle.java:14)
abricot
banane

Question: How to remove some element with a loop?

7 Answers

You need to use the iterator directly, and remove the item via that iterator.

for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
    String fruit = iterator.next();
    if ("banane".equals(fruit)) {
        iterator.remove();
    }
    System.out.println(fruit);
}

In addition to using the Iterator directly (which I would recommend) you can also store elements that you want to remove in a different list.

List<String> toRemove = new ArrayList<String>();
for (String fruit : list) {
    if ("banane".equals(fruit))
        toRemove.add(fruit);
    System.out.println(fruit);
}
for (String fruit : toRemove) {
    list.remove(fruit);
}

Mind you, I do not recommend this, it’s just an alternative. :)

Use a for loop, and loop over the collection in a reverse order. (That means, start with the last element, and loop to the first element. By doing so, you won't get problems by the indexes that change because of removing elements from the collection.

You get the exception in the example that you post, because the list over which your iterator iterates, has changed, which means that the iterator becomes invalid.

for(Iterator<String> iter = list.iterator(); iter.hasNext(); )
{
   String fruit = iter.next();
   if("banana".equals(fruit))
      iter.remove();
   System.out.println(fruit);
}

Similar to what Bombe suggested, but in less lines of code by iterating on the list copy, but removing from the original list;

List<String> temp = new ArrayList<String>(list);
for (String fruit : temp)
{
    if("banane".equals(fruit))
        list.remove(fruit);
    System.out.println(fruit);
}

Personally I think this looks nicer than iterating with an iterator.

Related