java Java中的并发修改异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13307471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:13:54  来源:igfitidea点击:

Concurrent Modification Exception in Java

javalistarraylistconcurrentmodificationlistiterator

提问by muneikh

I am getting the ConcurrentModificationException while executing this code. I am unable to figure out why it is happening?

我在执行此代码时收到 ConcurrentModificationException。我无法弄清楚为什么会这样?

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.

提前致谢。

回答by Rohit Jain

You are removing the element in the list using the listreference itself, which can throw ConcurrentModificationException. Note that, this might work sometimes, but not always, and is not guaranteed to work perfectly.

您正在使用list引用本身删除列表中的元素,这可能会抛出ConcurrentModificationException. 请注意,这有时可能会起作用,但并非总是如此,并且不能保证完美运行。

Also, even though you use Iteratorto 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.

此外,即使您用于Iterator迭代列表,您仍然不应该使用list.remove,您应该只用于iterator.remove()删除元素,否则无论您使用迭代器还是增强的 for 循环,它都不会产生任何区别。

So, use iterator.remove()to remove elements.

因此,用于iterator.remove()删除元素。

if (index != -1) {
    iterator.remove(value);
}

See this post: - java-efficient-equivalent-to-removing-while-iterating-a-collectionfor more detailed explanation.

请参阅这篇文章: - java-efficient-equivalent-to-removing-while-iterating-a-collection以获得更详细的解释。

回答by Egor

Simply because you're trying to remove elements from the ArrayListwhile iterating over them. To overcome this issue, use the java.util.concurrent.CopyOnWriteArrayList. Hope this helps.

仅仅是因为您试图ArrayList在迭代它们时从中删除元素。要解决此问题,请使用java.util.concurrent.CopyOnWriteArrayList。希望这可以帮助。

回答by Denys Séguret

What happens is that the ArrayList iterator isn't designed to enable modification while you're iterating on it.

发生的情况是 ArrayList 迭代器并非旨在在您对其进行迭代时启用修改。

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 :

从 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 :

如 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 removemethod of the iterator ensures the iterator is kept coherent.

为了避免这个问题,使用迭代器移除当前元素,而不是直接移除列表。remove迭代器的方法确保迭代器保持一致。

回答by someone

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

在迭代时您正在删除对象