3

I have a List, and I want to loop through that List and remove some record base on some condition. Here is what I do

public void foo(List<Bar> recordList){
     for(Bar bar : recordList){
         if(bar.someCondition()){
              recordList.remove(bar);
         }
     }
}

This code generate exception. If I use Iterator then it works fine

public void foo(List<Bar> recordList){
     Iterator<Bar> iter = recordList.iterator();
     while(iter.hasNext()){
         Bar bar = iter.next();
         if(bar.someCondition()){
              iter.remove();
         }
     }
}

I guess my question:

  1. Why the first piece of code does not work?

  2. How do I make the first piece of code work?

Vivien Barousse
  • 20,555
  • 2
  • 63
  • 64
Thang Pham
  • 38,125
  • 75
  • 201
  • 285

2 Answers2

10

The documentation is very clear on this.

http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Kal
  • 24,724
  • 7
  • 65
  • 65
6
  1. It doesn't work because you are modifying a collection WHILE iterating on it. It means you are changing its state and reading it at the same time. This provokes unexpected behaviours in the inners of the collection, and to prevent data corruption, an exception is thrown.

  2. You don't make it work. You have to use iterators.

Vivien Barousse
  • 20,555
  • 2
  • 63
  • 64