views:

171

answers:

5
    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?

+15  A: 

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);
}
Jon Skeet
For the one who will recognize himself : don't use for with incremental index and list.size() !! I wanted to change the code with a foreach loop and it was not the correct soluce. Yours is the one.
enguerran
just change `it.hasNext()` to `iterator.hasNext()` and it's perfect! (obvious.... but who knows....)
Carlos Heuberger
+1  A: 

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.

Frederik Gheysels
+3  A: 
for(Iterator<String> iter = list.iterator(); iter.hasNext(); )
{
   String fruit = iter.next();
   if("banana".equals(fruit))
      iter.remove();
   System.out.println(fruit);
}
Itay
+2  A: 

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. :)

Bombe
Your solution is too verbose
enguerran
Yes, it is. Which is why I would use the `Iterator`-based solution–which is what I have written.
Bombe
There is more than one way to do it, but most of those ways are wrong ;)
Jorn
There’s also more than one meaning for “wrong.” :)
Bombe
+1  A: 

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.

instanceofTom
I think it is easier to read
enguerran