LTH
LTH

Reputation: 1839

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").

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());
        }
    }
}

Upvotes: 0

Views: 333

Answers (3)

vcetinick
vcetinick

Reputation: 2017

You can't modify the enumeration while reading at same time. You need to make a copy of the ArrayList. Sometimes I shortcut by converting the ArrayList into an 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());
            }
        }
    }

Upvotes: 2

erickson
erickson

Reputation: 269697

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());
}

Upvotes: 3

David V
David V

Reputation: 11699

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)
{
...
}

Upvotes: 3

Related Questions