javaiteratorconcurrentmodificationfail-fast

Why isn't ConcurrentModificationException being thrown here?


Look at this little piece of code:

ArrayList al = new ArrayList();
al.add("AA");
al.add("AB");
al.add("AC");
Iterator it = al.iterator();
while(it.hasNext()){
String s = (String)it.next();
if(s.equals("AB")){
al.remove(1);
}
}

Since ArrayList has fail-fast iterator, and clearly, the given ArrayList isn't made of fixed size arrays (which would render the remove() method unusable), the above code should have thrown ConcurrentModificationException but yes, it does not.

Also, if I insert a print statement in the loop (as the first statement), it shows that the loop does not iterate the third time and that it exits gracefully.

I know it sounds too stupid but the only reason I could think of falsely is the fact that the removal of the element happens after the element has been traversed by the iterator. But that just cannot be the case as the modificationCount is still modified by removal and so it must throw the Exception.

Just doing

while(it.hasNext()){
it.next();
al.remove(1);
}

does throw ConcurrentModificationException though.

Any insights?


Solution

  • It happens because the hasNext() method does not check the modCount:

    public boolean hasNext() {
        return cursor != size;
    }
    

    So, after calling remove(1), the size of the list will be 2 just like the cursor, and hasNext() will return false. The next() method will never be called and modCount will never be checked.

    If you add a fourth element to the list before iterating, you will get the exception similarly to your second example.