2

I know that when you iterate over an arraylist with a forech loop, and then trying to remove an object from it, the concurrent modification exception is thrown. I have the following code, which produces this exception whenever I try to remove any of the list's objects.....except for the object "D". whenever I try to remove this object, there is NO EXCEPTION thrown. can someone please tell me why there is no exception? this is my code:

    List<String> myList = new ArrayList<>();
        myList.add("A");
        myList.add("B");
        myList.add("C");
        myList.add("D");
        myList.add("E");
    
        for (String s: myList) {
            if (s.equals("D")) {
                myList.remove("D");
            }
        }
        System.out.println(myList);
    
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Jessi
  • 69
  • 7
  • Likely because it's the last item in the list, but CMEs are a bit wickety and are really just a "best effort". There are other edge cases that demonstrate a "missing" CME, too. – Dave Newton Apr 20 '21 at 16:33
  • @DaveNewton Agree, but the item being removed is`"D"`, which is not the last element (although its position becomes the last element after removal). – Bohemian Apr 20 '21 at 16:34
  • 1
    Does this answer your question? [Java list's .remove method works only for second last object inside for each loop](https://stackoverflow.com/questions/16079931/java-lists-remove-method-works-only-for-second-last-object-inside-for-each-loo) – Dev-vruper Apr 20 '21 at 16:42
  • @Bohemian Oops. That's *definitely* a "bug" filed multiple times across versions :) – Dave Newton Apr 20 '21 at 16:47
  • It is because you are modifying a list you are iterating through, so it messes up the loop, because the element it was previously on doesnt exist anymore, and the lists size is less than it previously was. You will see this if you try to modify any list/map while it is being iterated over if you use a for loop – Joe Apr 20 '21 at 20:37

1 Answers1

1

From the ArrayList docs:

The iterators returned by this class'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.

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

The Iterator implementation on ArrayList tries to throw ConcurrentModification when it can easily detect it. In this particular case, it's hard because hasNext() just returns false, so no further methods are called on the iterator.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413