Why does List.addAll of a reversed subList of the list cause a ConcurrentModificationException
List.subList returns a live view of the list between the specified elements, not a copy of those elements (see documentation), therefore adding to the original list will also modify the sublist, which will lead to ConcurrentModificationException
(since what is being added and to what you add to also are modified at the same time).
list.subList(startIndex, endIndex+1)
You can fix a code by copying the list, like
List<Integer> toReverse = new ArrayList<>(list.subList(startIndex, endIndex+1));
from the documentation of ArrayList.subList :
The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa
So when you try to add items at the index of the subList 'view', it creates concurrent modification.
Issue lies here at ArrayList#checkForComodification
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
}
However in this particular case you don't need to manually re-add reversed sublist, since the reversion is performed on the original list. So all you need is just to drop
list.removeAll(...);
list.addAll(...);
and leave only this code:
List<Integer> toReverse = list.subList(startIndex, endIndex+1);
Collections.reverse(toReverse);