6

Fast-Fail : meaning that if they detect that the collection has changed since iteration began, they throw the unchecked ConcurrentModificationException.

I have written a test example to demonsterate this:

    String hi = "Hi";
    list.add(hi);
    list.add("Buy");
    System.out.println("list before: " + list);
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        String string = iterator.next();
        list.add("Good");
    }

the output is:

list before: [Hi, Buy]
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at thread.CollectionTest.main(CollectionTest.java:19)

which is expected. However, when an element is removed, the exception is not thrown:

    List<String> list = new ArrayList<>();

    String hi = "Hi";
    list.add(hi);
    list.add("Buy");
    System.out.println("list before: " + list);
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        String string = iterator.next();
        list.remove(hi);
    }

Output:

list before: [Hi, Buy]
list after: [Buy]

Why is that? both cases the list is modified.

9
  • 1
    Try removing before iterator.next() or try with 3 entries ... Commented Oct 28, 2015 at 12:26
  • ConcurrentModificationException will throw when you remove an element during iteration. In your case you call the next() and then you remove the object. Commented Oct 28, 2015 at 12:30
  • 1
    I am not 100% sure, therefore only comment. You call next then remove, then hasNext checks whether the next next call would return an element. It would not, so it returns false. And the next next call is not executed that would finally throw the exception. That would be my explanation, though as I said, not 100% sure. So if you had 3 elements, hasNext would return true and the following next would throw. Commented Oct 28, 2015 at 12:32
  • 1
    @sam , In ArrayList next() method will look checkForComodification. If the if (modCount != expectedModCount) then will throw.ConcurrentModificationException Commented Oct 28, 2015 at 12:37
  • 1
    This is probably a duplicate of stackoverflow.com/questions/14673653/… and others, but I'm always hesitant to use the dupehammer... :-/ Commented Oct 28, 2015 at 14:04

2 Answers 2

1

The point is that it is not hasNext() that checks for modification, but next(). In your "remove" scenario, you suppress the next call that would throw because there is no next element.

If you had 3 elements in the beginning, removing one would result in hasNext to be 'true'. Then the following next will throw the expected exception.

The JavaDoc points out that the "fail-fast" functionality works based on "best effort" and that it shall be used merely for detecting bugs rather than really depending on it for the program to behave correctly. Obviously because of side-effects like this one.

Sign up to request clarification or add additional context in comments.

Comments

0

ConcurrentModificationException will throw, you can make some modifications in the list during iteration.

After doing the modification in the list during iteration, if you try to access the next() or remove() using iterator, then it verify the modCount and expectedModCount and count is not same then it throw ConcurrentModificationException .

final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.