Why is it not possible to add values to my ArrayList in java after creating an object of iterator

Viewed 65

I am learning about collection classes in Java. I created an ArrayList and added some values to it.

package LearningJava;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;

public class Java{

    public static void  main(String args[]) {

        Collection values = new ArrayList();
        values.add(2);
        values.add(3);
        values.add(5);
        values.add(4);

        Iterator itr = values.iterator();
        for(int i = 0 ; i<values.size();i++) {
            System.out.println(itr.next());
        }
    }
}

I also iterated through this ArrayList.

If I add values after creating, the object of iterator throws an exception.

package LearningJava;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;

public class Java{

    public static void  main(String args[]) {

        Collection values = new ArrayList();
        values.add(2);
        values.add(3);
        values.add(5);
    
        Iterator itr = values.iterator();
        values.add(4);
    
        for(int i = 0 ; i<values.size();i++) {
            System.out.println(itr.next());
        }
    }
} 

It throws a java.util.ConcurrentModificationException. Why can't I add values after creating the object of iterator?

It is only throwing this exception in case of Iterator interface. When I create the object of other classes, it does not throw any exception.

package LearningJava;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;

public class Java{

    public static void  main(String args[]) {

        Collection values = new ArrayList();
        values.add(2);
        values.add(3);
        values.add(5);
    
         // creating the object of scanner instead of iterator's.
        Scanner input  = new Scanner(System.in);

        values.add(4);

        Iterator itr = values.iterator();
        for(int i = 0 ; i<values.size();i++) {
            System.out.println(itr.next());
        }
    }
}

Here it is not showing any errors. Why is this?

1 Answers

This behaviour is documented in the ArrayList's documentation:

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.

Adding an element counts as modifying the list "structurally", and note the wording "after the iterator is created".

The modification is detected when you start iterating over the list using next, which is where the exception is thrown.

See also Why is a ConcurrentModificationException thrown and how to debug it for details about what a ConcurrentModificationException is, though that question doesn't specifically address the case where you modify the collection immediately after creating the iterator, without calling next.

Related