In a list, adding or removing is considered as a modification. In your case you have made
5 modifications(additions).
‘for each’ loop works as follows,
1.It gets the iterator.
2.Checks for hasNext().
public boolean hasNext()
{
return cursor != size(); // cursor is zero initially.
}
3.If true, gets the next element using next().
public E next()
{
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
final void checkForComodification()
{
// Initially modCount = expectedModCount (our case 5)
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Repeats steps 2 and 3 till hasNext() returns false.
In case if we remove an element from the list , it’s size gets reduced and modCount is increased.
If we remove an element while iterating, modCount != expectedModCount get satisfied
and ConcurrentModificationException is thrown.
But removal of second last object is weird. Lets see how it works in your case.
Initially,
cursor = 0 size = 5 --> hasNext() succeeds and next() also succeeds
without exception.
cursor = 1 size = 5 --> hasNext() succeeds and next() also succeeds
without exception.
cursor = 2 size = 5 --> hasNext() succeeds and next() also succeeds
without exception.
cursor = 3 size = 5 --> hasNext() succeeds and next() also succeeds
without exception.
In your case as you remove ‘d’ , size gets reduced to 4.
cursor = 4 size = 4 --> hasNext() does not succeed and next() is
skipped.
In other cases, ConcurrentModificationException will be thrown as modCount != expectedModCount.
In this case, this check does not take place.
If you try to print your element while iterating, only four entries will be printed. Last element is skipped.
Hope I made clear.