Saturday, November 10, 2018

Java Collections - ConcurrentModificationException

Greetings!

When you use a collection and suddenly encounter ConcurrentModificationException it is very confusing. Why are we getting this when we are not using multi-threading?

Actually this doesn't mean you are using multi-threading. This means that the collection in used is modified (add/remove).

For an example let's say we want remove multiples of 3 from an array list.


List<Integer> numbers = IntStream.range(1, 20).boxed().collect(toList());

for (Integer number : numbers) {
    if (number % 3 == 0) {
        numbers.remove(number - 1);
    }
}


This little program will throw java.util.ConcurrentModificationException because we are modifying the collection directly while iterating.

Underline iterator is implemented so that it checks for any modification. If it found any modification it throws new ConcurrentModificationException.

Instead of removing items from the collection, we need to remove it from the iterator.


List<Integer> numbers = IntStream.range(1, 20).boxed().collect(toList());

Iterator<Integer> iterator = numbers.iterator();

while (iterator.hasNext()) {
    if (iterator.next() % 3 == 0) {
        iterator.remove();
    }
}


In Java 8, above while loop has been added to Collection interface as a default method;


List<Integer> numbers = IntStream.range(1, 20).boxed().collect(toList());

numbers.removeIf(number -> number % 3 == 0);




No comments:

Post a Comment