Why isn't ConcurrentModificationException thrown here?

Take a 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 a fail-safe iterator , and obviously the given ArrayList does not consist of fixed-size arrays (to make the method remove()

unusable), the above code should have been thrown ConcurrentModificationException

, but yes it is not.

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

I know this sounds too silly, but the only reason I could be wrong is the fact that the removal of an element occurs after the element has gone through the iterator. But this simply cannot be the case as it modificationCount

is still modified by deletion and therefore should throw an exception.

Just do

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

      

indeed throws ConcurrentModificationException.

Any ideas? Thank!

+3


source to share


2 answers


This is because the method hasNext()

does not check modCount

:

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

      



So, after the call, the remove(1)

size of the list will be exactly the same as the cursor, and hasNext()

will return false. The method next()

will never be called and modCount

will never be tested.

If you add the fourth item to the list before repeating, you get an exception similar to your second example.

+2


source


Concurrent modification check happens only during the Iterator call next()

, not in its call hasNext()

, as described in Bubletan's answer .

The javaArrayList

documentation for clearly states that



Failed iterators throw ConcurrentModificationException at the best possible way. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the bad behavior of iterators should only be used to catch errors.

So, it is bad programming practice to modify a collection while iterating over it.

0


source







All Articles