2

It is common to iterate list of elements. Check some conditions and remove some elements from list.

for (ChildClass childItem : parent.getChildList()) {
    if (childItem.isRemoveCandidat()) {
    parent.getChildList().remove(childItem);    
    }
}

But in this case java.util.ConcurrentModificationException is thrown.

What is the best program pattern in this case?

Balconsky
  • 2,234
  • 3
  • 26
  • 39

3 Answers3

11

Use an Iterator. If your list supports Iterator.remove you can use it instead! It won't throw the exception.

Iteartor<ChildClass> it = parent.getChildList().iterator();
while (it.hasNext())
    if (it.next().isRemoveCandidat()) 
        it.remove();

Note: The ConcurrentModificationException is thrown when you have "started" iterating over a collection and modifies the list during the iteration time (eg in your case it doesn't have anything todo with concurrency. You are using the List.remove operation during the iteration and that is the same in this case..).


Full example:

public static void main(String[] args) {

    List<Integer> list = new LinkedList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);

    for (Iterator<Integer> it = list.iterator(); it.hasNext(); )
        if (it.next().equals(2))
            it.remove();

    System.out.println(list); // prints "[1, 3]"
}
dacwe
  • 43,066
  • 12
  • 116
  • 140
1

another option is:

for(int i = parent.getChildList().length - 1; i > -1; i--) {

    if(parent.getChildList().get(i).isRemoveCandidat()) {
        parent.getChildList().remove(i);
    }
}
Tom
  • 4,096
  • 2
  • 24
  • 38
1

You can use ListItrerator

for(ListIterator it = list.listIterator(); it.hasNext();){
    SomeObject obj = it.next();
    if(obj.somecond()){
        it.remove();
    }
}

You can also use Iterator. But the flexibility of ListItrerator over Iterator is you can traverse the list both way.

Tapas Bose
  • 28,796
  • 74
  • 215
  • 331