11
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class MyList {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>();

        al.add("S1");
        al.add("S2");
        al.add("S3");
        al.add("S4");

        Iterator<String> lir = al.iterator();

        while (lir.hasNext()) {
            System.out.println(lir.next());
        }

        al.add(2, "inserted");

        while (lir.hasNext()) {
           System.out.println(lir.next());
        }
    }
}

The particular piece of code throws an error:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at collections.MyList.main(MyList.java:32)
1
  • I bet I can find more than 10 duplicates in SO. Commented Aug 14, 2013 at 9:06

3 Answers 3

7

It happens due to array list is modified after creation of Iterator.

The iterators returned by this ArrayList'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. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Documentation

Iterator<String> lir = al.iterator(); // Iterator created

while (lir.hasNext()) 
    System.out.println(lir.next());
al.add(2, "inserted"); // List is modified here
while (lir.hasNext()) 
    System.out.println(lir.next());// Again it try to access list 

What you should do here create new iterator object after modification.

...
al.add(2, "inserted");
lir = al.iterator();
while (lir.hasNext()) 
    System.out.println(lir.next());
Sign up to request clarification or add additional context in comments.

Comments

3

You are modifying the Collection and then trying to use the same iterator.

  1. Get the Collection iterator again

    al.add(2, "inserted");
    Iterator<String> lirNew = al.iterator();
    while (lirNew.hasNext()) {
    System.out.println(lirNew.next());
    }
    
  2. or Use ListIterator

    ArrayList<String> al = new ArrayList<String>();
    
    al.add("S1");
    al.add("S2");
    al.add("S3");
    al.add("S4");
    
    ListIterator<String> lir = al.listIterator();
    
    while (lir.hasNext()) {
        System.out.println(lir.next());
    
    }
    
    lir.add("insert");
    
    while (lir.hasNext()) {
        System.out.println(lir.next());
    
    }
    

Comments

0

You add object to list, after the iterator is instanced. This will change the value of modCount in inner class AbstractList$Itr.class. next() method of iterator will call checkForComodification() method, which throws a ConcurrentModificationException. And this is so called fail-fast.

 //add in abstractList
 public void add(int index, E element) {
    if (index<0 || index>size)
        throw new IndexOutOfBoundsException();
    checkForComodification();
    l.add(index+offset, element);
    expectedModCount = l.modCount;
    size++;
    modCount++;  //modCount changed
}

In AbstractList$Itr

int expectedModCount;

public E next() {
        checkForComodification(); // cause ConcurrentModificationException
    try {
    E next = get(cursor);
    lastRet = cursor++;
    return next;
    } catch (IndexOutOfBoundsException e) {
    checkForComodification();
    throw new NoSuchElementException();
    }
}

 private void checkForComodification() {
    if (l.modCount != expectedModCount)  //modCount not equals to itr.expectedModCount
        throw new ConcurrentModificationException();
}

redo this code after your add:

al.add(2, "inserted");
lir = al.iterator();

2 Comments

yah but why does this happens when I have limited the scope of iterator to while loop
It is not caused by scope, but your add() invocation. You'd better to read the jdk source code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.