Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.
 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 gives 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)
share|improve this question
 
I bet I can find more than 10 duplicates in SO. –  kocko Aug 14 at 9:06
add comment

marked as duplicate by Kris, RAS, EJP, Puggan Se, RGraham Aug 14 at 11:04

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3 Answers

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());
share|improve this answer
1  
+1 nice explanation –  JqueryLearner Aug 14 at 9:09
add comment

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());
    
    }
    
share|improve this answer
add comment

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();
share|improve this answer
 
yah but why does this happens when I have limited the scope of iterator to while loop –  user2681668 Aug 22 at 8:57
 
It is not caused by scope, but your add() invocation. You'd better to read the jdk source code. –  criszhao Aug 22 at 9:14
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.