Question

In my code:

    Collection<String> c = new ArrayList<>();
    Iterator<String> it = c.iterator();
    c.add("Hello");
    System.out.println(it.next());

Exception occures, because my collection changed after iterator created.

But what about in this code:

 ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    for (Integer integer : list) {     // Exception is here
        if (integer.equals(2)) {
            list.remove(integer);
        }
    }

Why exception occured?

In second code, i did changes in my collection before for-each loop.

Was it helpful?

Solution

In the second loop, it's the same reason - you are removing an element from the list.

To remove elements from a List while looping through it, either use standard old-fashioned for loops:

for(int i=0;i<list.size();i++) {

and remove list items inside that loop or use a ListIterator to iterate over the list.

OTHER TIPS

Exception is because you are iterating as well as removing the element from the list

 for (Integer integer : list) {     // Exception is here because you are iterating and also removing the elements of same list here
        if (integer.equals(2)) {
            list.remove(integer);
        }

You are also changing your collection inside the for-each loop:

  list.remove(integer);

If you need to remove elements while iterating, you either keep track of the indices you need to delete and delete them after the for-each loop finishes, or you use a Collection that allows concurrent modifications.

You could instead use CopyOnWriteArrayList, it's not very efficient, but solves the ConcurrentModificationException, and you can use safely the remove method.

Here's the cleanest way to never get ConcurrentModificationExceptions if you need to remove elements while iterating using the better syntax:

// utility method somewhere
public static < T > Iterable< T > remainingIn( final Iterator< T > itT ) {
    return new Iterable< T >() {
        @Override
        public Iterator< T > iterator() {
            return itT;
        }
    }
}

// usage example
Iterator< Integer > itI = list.iterator();
for ( Integer integer : remainingIn( itI ) ) {
    if ( integer.equals( 2 ) ) {
        itI.remove();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top