tags:

views:

113

answers:

5

Take this Java code:

for (ContactsReduced curContact : allcontacts) {
 ..........
 allcontacts.remove(curContact);
}

I do based on a condition a remove, will the foreach miss the next item in order, and do we need to step back(somehow)?

A: 

It's definitely advised against to tamper with the collection while iterating it. I'm not sure if Java even allows it; it might throw an exception. I know C# does...

David Hedlund
A: 

Iterator will fail with ConcurrentModificationException. That's how collection framework is designed.

Luno
+5  A: 

That code will break with most collections - other than a few collections such as those in java.util.concurrent, modifying a collection while iterating over it isn't supported.

A few options:

  • Obtain and use an iterator explicitly (call iterator() on the collection) instead of an enhanced for loop, and call iterator.remove() to remove an item
  • Use a plain for loop, either moving forwards and stepping back after the removal or moving backwards from the end
  • Maintain a separate list of items to remove, and then remove them after iterating
Jon Skeet
It is probably worth mentioning that this "feature" is called fail-fast. It should help to navigate around when reading relevant Javadocs.
mindas
A: 
List<Integer> al = new ArrayList<Integer>();
        for(int i=0;i<10;i++){
            al.add(i);
        }
        for(Integer x:al){
            al.remove(x);
            System.out.println(al);
        }

Well, the question is interesting so I tried it in my system and this is wat i got.

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
    at java.util.AbstractList$Itr.next(Unknown Source)
    at test.Main.main(Main.java:17)
Bragboy
+1  A: 

Take a look at the section on iterators on the collection interface tutorial

Use Iterator instead of the for-each construct when you need to remove the current element. The for-each construct hides the iterator, so you cannot call remove. Therefore, the for-each construct is not usable for filtering.

Note that Iterator.remove is the only safe way to modify a collection during iteration

Soldier.moth