简体   繁体   English

Java:修改ArrayList时获取并发修改异常

[英]Java: Getting Concurrent Modification Exception when modifying ArrayList

So I'm writing a program which keeps a track of various documents like e-mails, memos, and reports. 因此,我正在编写一个程序来跟踪各种文档,例如电子邮件,备忘录和报告。 The documents are stored in an ArrayList called "active" by default, but the user has the option of transferring them to another ArrayList called "archive", using an identification code("docId"). 默认情况下,文档存储在一个称为“活动”的ArrayList中,但是用户可以选择使用标识码(“ docId”)将它们传输到另一个称为“存档”的ArrayList中。

I thought that this would be pretty straightforward but I'm running into this error and would appreciate your help in resolving it. 我以为这很简单,但是我遇到了这个错误,感谢您为解决该错误提供的帮助。 Here's my code: 这是我的代码:

private static ArrayList active = new ArrayList();
private static ArrayList archive = new ArrayList(); 

public static void archiveDocument(double docId)
{       
    if(active.isEmpty() == true)
    {
        System.out.println(Messages.emptyList());
    }
    else
    {
        for(Object a : active)
        {
            Document doc = (Document) a;

            if(doc.getIdNum() == docId)
            {
                archive.add(a);
                active.remove(a);

                System.out.printf(Messages.enteredIntoArchive(), doc.getIdNum());
            }
            else System.out.println(Messages.notFound());
        }
    }
}

You are trying to change the list while iterating over its enumerator. 您正在尝试遍历其枚举器时更改列表。

for(Object a : active)

This starts an enumeration 这开始一个枚举

active.remove(a);

You modify it here. 您在这里修改它。

One easy fix is to copy the list before enumerating over it and then enumerate over the copy. 一种简单的解决方法是先复制列表,然后再枚举列表,然后再枚举副本。

ArrayList activeCopy = new ArrayList(active);
for(Object a : activeCopy)
{
...
}

If you want to remove during iteration, use an explicit iterator: 如果要在迭代过程中删除,请使用显式迭代器:

Iterator i = active.iterator();
while (i.hasNext()) {
  Document doc = (Document) i.next();
  if (doc.getIdNum() == docId) {
    archive.add(doc);
    i.remove();
    System.out.printf(Messages.enteredIntoArchive(), doc.getIdNum());
  }
  else
    System.out.println(Messages.notFound());
}

You can't modify the enumeration while reading at same time. 您无法在同时阅读时修改枚举。 You need to make a copy of the ArrayList . 您需要复制ArrayList Sometimes I shortcut by converting the ArrayList into an array[] . 有时我通过将ArrayList转换为array[]捷径。

public void archiveDocument(double docId) {
        if (active.isEmpty() == true) {
            System.out.println(Messages.emptyList());
        } else {
            for (Object a : active.toArray(new Object[0])) {
                Document doc = (Document) a;

                if (doc.getIdNum() == docId) {
                    archive.add(a);
                    active.remove(a);

                    System.out.printf(Messages.enteredIntoArchive(), doc
                            .getIdNum());
                } else
                    System.out.println(Messages.notFound());
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM