Was trying to implement in-place purge on a list.
Iterator<Integer> itr = ls.iterator();
for (Integer x : ls) {
int count = 0;
while(itr.hasNext()){
if (itr.next().equals(x)) {
count++;
if (count > 1) {
itr.remove();
}
}
}
}
Exception in thread "main" java.util.ConcurrentModificationException
Iterator<Integer> iterator = numbers.iterator();
while (iterator.hasNext()) {
if (iterator.next() == 1) {
iterator.remove(); // Doesn't throw exception
}
}
However, with just one loop thought it doesn't. Why ?
what is the reasoning for this behavior
You have two iterators over
lshere:ls.iterator();for (Integer x : ls).If you call
remove()on the first iterator, it invalidates the second iterator, meaning any invocations ofnext()on the second iterator cause (or are prone to causing) aConcurrentModificationExceptionto be thrown.A possible way to do an in-place deduplication might be like this:
This shifts elements that haven't been seen before to the left in the array; and then removes all other elements from the array afterwards.
Changing the list in the loop doesn't result in a
ConcurrentModificationExceptionbecause there is no structural modification to the list.