-3

I'm trying to practice java's Iterators, and to be more accurate, Im trying to understand the concurrentModificationException.

When this exception is thrown? From what I've read, this exception is thrown on any object removal when iterating with a for loop and using collection's remove method. But when Im practice this on my IDE, I see this exception is thrown only when removing the first or last element. Can anyone please clarify this issue?

Thank you.

Jessi
  • 69
  • 7
  • You'll need to show an example of what you're doing. When you iterate over the list and try to change the list at the same time you'll get a CCME. – matt Apr 19 '21 at 08:17
  • Can you [edit] your question and post a [mcve]? – Abra Apr 19 '21 at 08:36

1 Answers1

1

a ConcurrentModificationException can is thrown in situations when you're trying to modify a collection while it can't be modified. A simple example of this happening is code such as this:

List<Integer> l = new ArrayList<>();
...
Iterator<Integer> iter = l.iterator();
l.remove(0);
iter.next();

Here we've created an iterator, and then removed the first element of the ArrayList. This action invalidates the iterator, and it isn't clear which element it should now return. So the call to iter.next() throws a ConcurrentModificationException.

You can see this in ArrayList's Iterator implementation (link):

public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}

As you can see, the first thing a call to next() does is check whether the state of this Iterator is still valid by checking whether the ArrayList has been modified.

But when Im practice this on my IDE, I see this exception is thrown only when removing the first or last element.

That's not the case. Any modification of the list's structure will throw the exception. Let's try replacing the l.remove(0) line with something different.

  • How about removing an item from the middle - l.remove(3)? It throws an exception.

  • How about l.add(3) or l.add(1,1)? They both throw an exception.

  • How about l.remove(0), followed by l.add(0). This maintains the list's length, so it should be fine, right? No. It also throws an exception.

The only modification we're allowed is replacing an element in-place using a set() call such as set(1,1) because it doesn't affect the list's structure. This has nothing to do with the first or last element of the list.

Malt
  • 28,965
  • 9
  • 65
  • 105
  • Thanx! Even though I know this in theory, but on practice, I get this exception only when removing the first element or the last element. If I'll try to remove the element at index 1 for example, not exception is thrown. This is what Im trying to understand. – Jessi Apr 19 '21 at 08:39
  • @Jessi I've edited the answer to address the first/last element – Malt Apr 19 '21 at 08:48
  • @Jessi you are describing very specific behavior that is not true in general. If you give a complete example somebody might be able to tell you why. – matt Apr 19 '21 at 10:35