When removing inside foreach, do we need to step back
Take this Java code:
for (ContactsReduced curContact : allco开发者_高级运维ntacts) {
..........
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)?
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 calliterator.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
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
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)
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...
Iterator will fail with ConcurrentModificationException. That's how collection framework is designed.
精彩评论