I Question:
In our daily development, we may occasionally encounter operations that need to be in the loop (such as adding or modifying). If we directly use the for loop to traverse, it will lead to
Abnormal error reporting:
java.util.ConcurrentModificationException: null
Case:
In the official document, ConcurrentModificationException is described as follows:
public class ConcurrentModificationException extends RuntimeException
This exception is thrown when the method detects concurrent modification of the object but does not allow such modification.
For example, when a thread iterates over a Collection, another thread is usually not allowed to modify the Collection linearly. Usually in these cases, the result of iteration is uncertain. If this behavior is detected, some iterator implementations (including all generic Collection implementations provided by JRE) may choose to throw this exception.
ConcurrentModificationException is a common exception in Java, especially when using collection classes.
2: Reason:
After the addition operation, the values of expectedModCount and modCount of the collection are inconsistent. The function of these two variables is to record the modification times. The two are not equal, so they will be thrown wrong.
There is a judgment check in the ArrayList source code implementation
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
From this code, we can see that what is returned is a reference to Itr type object. We then look at the specific implementation of Itr. We find the specific implementation of Itr class in ArrayList class, which is a member internal class of ArrayList. The following code is all the implementations of Itr class:
There are several member variables:
- cursor: indicates the index of the next element to be accessed, as can be seen from the concrete implementation of the next() method
- lastRet: indicates the index of the last accessed element
- expectedModCount: indicates the expected value of the number of modifications to ArrayList. Its initial value is modCount.
- modCount is a member variable in the AbstractList class
/** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") 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]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
III solve
It can be solved by index traversal (ordinary for loop), as follows
After reading, Congratulations, you know a little bit!!!
The more you know, the more you don't know!
~Thank you for reading. Your support is the biggest driving force for my study! Come on, strangers work together and encourage each other!!
Note: if there are any improvements or mistakes in this article, the great gods are welcome to specify one or two~~