ConcurrentModificationException for ArrayList

JavaCollectionsConcurrency

Java Problem Overview


I have the following piece of code:

private String toString(List<DrugStrength> aDrugStrengthList) {
    StringBuilder str = new StringBuilder();
        for (DrugStrength aDrugStrength : aDrugStrengthList) {
            if (!aDrugStrength.isValidDrugDescription()) {
                aDrugStrengthList.remove(aDrugStrength);
            }
        }
        str.append(aDrugStrengthList);
        if (str.indexOf("]") != -1) {
            str.insert(str.lastIndexOf("]"), "\n          " );
        }
    return str.toString();
}

When I try to run it, I get ConcurrentModificationException, can anyone explain why it happens, even if the code is running in same thread? And how could I avoid it?

Java Solutions


Solution 1 - Java

You can't remove from list if you're browsing it with "for each" loop. You can use Iterator. Replace:

for (DrugStrength aDrugStrength : aDrugStrengthList) {
    if (!aDrugStrength.isValidDrugDescription()) {
        aDrugStrengthList.remove(aDrugStrength);
    }
}

With:

for (Iterator<DrugStrength> it = aDrugStrengthList.iterator(); it.hasNext(); ) {
    DrugStrength aDrugStrength = it.next();
    if (!aDrugStrength.isValidDrugDescription()) {
        it.remove();
    }
}

Solution 2 - Java

Like the other answers say, you can't remove an item from a collection you're iterating over. You can get around this by explicitly using an Iterator and removing the item there.

Iterator<Item> iter = list.iterator();
while(iter.hasNext()) {
  Item blah = iter.next();
  if(...) {
    iter.remove(); // Removes the 'current' item
  }
}

Solution 3 - Java

I like a reverse order for loop such as:

int size = list.size();
for (int i = size - 1; i >= 0; i--) {
    if(remove){
        list.remove(i);
    }
}

because it doesn't require learning any new data structures or classes.

Solution 4 - Java

there should has a concurrent implemention of List interface supporting such operation.

try java.util.concurrent.CopyOnWriteArrayList.class

Solution 5 - Java

While iterating through the loop, you are trying to change the List value in the remove() operation. This will result in ConcurrentModificationException.

Follow the below code, which will achieve what you want and yet will not throw any exceptions

private String toString(List aDrugStrengthList) {
        StringBuilder str = new StringBuilder();
    List removalList = new ArrayList();
    for (DrugStrength aDrugStrength : aDrugStrengthList) {
        if (!aDrugStrength.isValidDrugDescription()) {
            removalList.add(aDrugStrength);
        }
    }
    aDrugStrengthList.removeAll(removalList);
    str.append(aDrugStrengthList);
    if (str.indexOf("]") != -1) {
        str.insert(str.lastIndexOf("]"), "\n          " );
    }
    return str.toString();
}

Solution 6 - Java

We can use concurrent collection classes to avoid ConcurrentModificationException while iterating over a collection, for example CopyOnWriteArrayList instead of ArrayList.

Check this post for ConcurrentHashMap

http://www.journaldev.com/122/hashmap-vs-concurrenthashmap-%E2%80%93-example-and-exploring-iterator

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmabuzerView Question on Stackoverflow
Solution 1 - JavaKonrad GarusView Answer on Stackoverflow
Solution 2 - JavaEdward DaleView Answer on Stackoverflow
Solution 3 - JavafromanView Answer on Stackoverflow
Solution 4 - JavaidiotgeniusView Answer on Stackoverflow
Solution 5 - JavabragboyView Answer on Stackoverflow
Solution 6 - JavaSuganthan Madhavan PillaiView Answer on Stackoverflow