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
  • 1
  • 4

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,757
  • 3
  • 29
  • 41
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,717
  • 1
  • 18
  • 30
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
  • 21,933
  • 14
  • 72
  • 101
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,315
  • 2
  • 20
  • 28
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,209
  • 17
  • 22