问题
I am getting the ConcurrentModificationException while executing this code. I am unable to figure out why it is happening?
private void verifyBookingIfAvailable(ArrayList<Integer> list, int id) {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
int value = iterator.next();
if (value == id) {
int index = list.indexOf(id);
if (index != -1) {
list.remove(index);
}
}
}
}
Thanks in advance.
回答1:
You are removing the element in the list using the list
reference itself, which can throw ConcurrentModificationException
. Note that, this might work sometimes, but not always, and is not guaranteed to work perfectly.
Also, even though you use Iterator
to iterate your list, you still shouldn't use list.remove
, you should only use iterator.remove()
to remove the elements, else it won't make any difference, whether you use iterators or enhanced for-loop.
So, use iterator.remove()
to remove elements.
if (index != -1) {
iterator.remove(value);
}
See this post: - java-efficient-equivalent-to-removing-while-iterating-a-collection for more detailed explanation.
回答2:
Simply because you're trying to remove elements from the ArrayList
while iterating over them. To overcome this issue, use the java.util.concurrent.CopyOnWriteArrayList. Hope this helps.
回答3:
What happens is that the ArrayList iterator isn't designed to enable modification while you're iterating on it.
So, to avoid more serious bugs coming from incoherent data, it has a modification count which is updated when you remove an item and checked when you iterate :
From ArrayList.java :
411 public E remove(int index) {
412 rangeCheck(index);
413
414 modCount++;
415 E oldValue = elementData(index);
416
417 int numMoved = size - index - 1;
418 if (numMoved > 0)
419 System.arraycopy(elementData, index+1, elementData, index,
420 numMoved);
421 elementData[--size] = null; // Let gc do its work
422
423 return oldValue;
424 }
...
779
780 final void checkForComodification() {
781 if (modCount != expectedModCount)
782 throw new ConcurrentModificationException();
783 }
As specified in the javadoc :
The returned list iterator is fail-fast.
To avoid this problem, use the iterator to remove the current element, not the list directly. The remove
method of the iterator ensures the iterator is kept coherent.
回答4:
Try this
private void verifyBookingIfAvailable(ArrayList<Integer> list, int id) {
List<Integer> tempList =new ArrayList<Integer>();
tempList.addAll(list);
for(Integer value :tempList) {
if (value == 1) {
int index = tempList.indexOf(1);
if (index != -1) {
list.remove(index);
}
}
}
}
while iteration you are removing objects
来源:https://stackoverflow.com/questions/13307471/concurrent-modification-exception-in-java