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

Time:08-13

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?

CodePudding user response:

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.

CodePudding user response:

ConcurrentModificationException is being thrown because you are adding to (concurrently modifying) the collection that the iterator was taken on; Not because a new object is created.

This is correct behaviour, as per ConcurrenModificationException docs.

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

  • Related