尝试从ArrayList中删除项目时发生ConcurrentModificationException

时间:2018-12-11 15:37:34

标签: android arraylist

实际上,在按下按钮后,我有一种方法可以检查我的itemStorico ArrayList中是否存在来自itemModel的新添加的项,然后如果该项目存在于名为itemModel的新列表中,我将从itemStorico中删除旧项并添加新项一个,否则只需添加新项目而不会删除旧项目。

但是我遇到以下错误:

2018-12-11 16:34:04.067 29033-29033/it.gabtamagnini.realco E/AndroidRuntime: FATAL EXCEPTION: main
    Process: it.gabtamagnini.realco, PID: 29033
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.next(ArrayList.java:831)
        at it.gabtamagnini.realco.OrdiniActivity.saveStorico(OrdiniActivity.java:1396)
        at it.gabtamagnini.realco.OrdiniActivity$29.onClick(OrdiniActivity.java:1368)
        at android.view.View.performClick(View.java:5637)
        at android.view.View$PerformClick.run(View.java:22433)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6130)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

这是我方法中的代码:

 for(ItemModel itemModels : itemModel){
            boolean exist = false;
            for(ItemModel itemModel2 : itemStorico){
                if(itemModels.getCodiceArticolo().contains(itemModel2.getCodiceArticolo())) {
                    itemStorico.remove(itemModel2);
                    itemStorico.add(itemModels);
                    exist = true;
                }
            }
            if(!exist) {
                itemStorico.add(itemModels);
            }
        }

2 个答案:

答案 0 :(得分:1)

您不能从“ for-each”循环(remove()结构)内部调用for (item : collection)。这样做会抛出ConcurrentModificationException

如果您要循环播放并在循环播放时删除项目,则可以使用传统的“ for”循环:

for (int i = 0; i < itemStorico.size(); ++i) {
    ItemModel itemModel2 = itemStorico.get(i);
    if (...) {
        itemStorico.remove(i);
        ...
    }
}

但是,这将引入一个细微的错误。想象一下,您正在遍历[a,b,c,d]。如果您位于索引1并从集合中删除b,那么所有内容都会“滑过”,您将拥有[a,c,d]。下次查看索引2时,您将跳过c

您可以通过在删除时手动减小索引来避免该错误,但这有点毛病。

...
    itemStorico.remove(i);
    --i;
...

您还可以通过使用集合的iterator()来完全避免该问题。

for (Iterator<ItemModel> iterator = itemStorico.iterator(); iterator.hasNext(); ) {
    ItemModel itemModel2 = iterator.next();
    if (...) {
        iterator.remove();
        ...
    }
}

答案 1 :(得分:0)

for(ItemModel itemModel2 : itemStorico){
            if(itemModels.getCodiceArticolo().contains(itemModel2.getCodiceArticolo())) {
                itemStorico.remove(itemModel2);

您正在迭代列表时从列表中删除该元素。你不能!

为避免出现此并发问题,您可以使用迭代器,但请查看此答案以说明您需要了解的所有信息:Remove elements from collection while iterating