0

I'm getting a Concurrent Modification Exception when running the for each loop of the following code:

if (entityList.isEmpty()) {
    entityList.add(entity);
}
else {
    for (Entity e: entityList) {
        if (e.getName().equals(p.toString())) {
            e.setOccurrence(e.getOccurrence() + 1);
        }
        else {
            entityList.add(entity);
        }
    }
}

This happens because I try to read from the entityList and write to it in the same thread, right? I'm not sure how to resolve the issue for working with an Iterator object only seems to make sense if the exception occurs when removing list items.

Pete
  • 502
  • 1
  • 6
  • 20
  • 1
    Yes it's a duplicate: http://stackoverflow.com/questions/223918/iterating-through-a-list-avoiding-concurrentmodificationexception-when-removing – IlGala Jun 17 '15 at 09:50
  • @IlGala that other question is about **removing** elements while iterating, not about **adding** elements while iterating. – Jesper Jun 17 '15 at 10:01

3 Answers3

2

You get that exception because you are modifying the list inside the loop (you are calling add on the list inside the loop).

Put the entities that you want to add in a temporary list, and add them to the original list after the loop:

if (entityList.isEmpty()) {
    entityList.add(entity);
}
else {
    List<Entity> tempList = new ArrayList<>();

    for (Entity e: entityList) {
        if (e.getName().equals(p.toString())) {
            e.setOccurrence(e.getOccurrence() + 1);
        }
        else {
            tempList.add(entity);
        }
    }

    entityList.addAll(tempList);
}
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 1
    @MuratK. Using an `Iterator` is not going to help you here. You can use it to *remove* elements when iterating (by calling `remove` on the `Iterator` instead of on the `List`), but not to *add* elements while iterating. – Jesper Jun 17 '15 at 09:52
  • 1
    [ListIterator#add()](http://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html#add%28E%29) ? – Murat Karagöz Jun 17 '15 at 09:55
  • @MuratK. Ok, then you should have said "use a **List**Iterator". – Jesper Jun 17 '15 at 09:58
  • Either way, as long as it solves the problem it's fine. – Murat Karagöz Jun 17 '15 at 10:00
0

Do you really mean to add entity to the list for every entry that's not matching? If your list has 10 elements and only one of them matches, you will add 9 new elements to the list. That is probably not what you want.

Consider using a Map<String,Entity> instead of a List.

Map<String,Entity> entityMap;

......

String name = p.toString();
Entity match = entityMap.get(name);
if (match == null) {
    entityMap.put(name, entity);
} else {
    match.setOccurence(match.getOccurence() + 1);
}
Misha
  • 27,433
  • 6
  • 62
  • 78
0

Instead of for each style loop or Iterator use the old for loop. Like...

for(int index=0; index < entityList.size(); index++){
 Entity e = entityList.get(index);
 if (e.getName().equals(p.toString())) {
        e.setOccurrence(e.getOccurrence() + 1);
    }

}
pundit
  • 322
  • 1
  • 7