0

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.

user3281108
  • 35
  • 1
  • 3

5 Answers5

5

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.

Martin Dinov
  • 8,480
  • 2
  • 27
  • 40
2

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);
        }
Girish
  • 1,677
  • 1
  • 17
  • 29
1

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.

Daniel
  • 19,718
  • 12
  • 63
  • 86
1

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

yamilmedina
  • 3,145
  • 2
  • 18
  • 27
0

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();
    }
}
Judge Mental
  • 5,129
  • 16
  • 21