Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When removing inside foreach, do we need to step back

Tags:

java

foreach

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

like image 419
Pentium10 Avatar asked May 17 '10 08:05

Pentium10


3 Answers

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
like image 185
Jon Skeet Avatar answered Oct 14 '22 06:10

Jon Skeet


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

like image 28
Bobby Avatar answered Oct 14 '22 08:10

Bobby


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)
like image 35
bragboy Avatar answered Oct 14 '22 06:10

bragboy