javaconcurrentmodificationlistiterator

When do we (or when do we not) allow concurrent modification when using ListIterator?


For instance, let's say there is a some Collections#reverse(List) operation that uses the ListIterator as such:

var forwardItr = list.listIterator();
var reverseItr = list.listIterator(list.size());
while (forwardItr.nextIndex() < reverseItr.previousIndex()) {
  var forward = forwardItr.next();
  var reverse = reverseItr.previous();
  forwardItr.set(reverse)
  reverseItr.set(forward)
}

Should there ever be some implementation that throws a ConcurrentModificationException from ListIterator#set? Or rather, is there a particular type of modification (i.e. "structural") that should cause an exception throw? Is it implied that some implementations of List may justifiably throw an exception from the aforementioned operation?


Solution

  • Should there ever be some implementation that throws a ConcurrentModificationException from ListIterator::set?

    The answer is that there could be.

    The javadocs for List, ListIterator and ConcurrentModificationException talk it terms of modifications that are permissible and not permissible without going into the specifics of what is permissible. If you look at the javadocs for (say) ArrayList you will see that it says that changes that don't cause structural modifications are permissible during an iteration. However, that doesn't apply to all list types; e.g. all modifications are permitted during an iteration for a CopyOnWriteArrayList.

    A custom list type could place different constraints on modifications.

    Or rather, is there a particular type of modification (i.e. "structural") that should cause an exception throw?

    Well ListIterator::set is not a structural modification. But for some list classes a "structural" modification during iteration will lead to a CME.

    Other (hypothetical) examples:

    Arguable these could be a different exceptions; e.g. UnsupportedOperationException. My reading of the javadocs are that CME would be appropriate.

    Is it implied that some implementations of List may justifiably throw an exception from the aforementioned operation?

    Yes. A custom List implementation could do all sorts of "interesting" things so long as it conforms to the behaviors defined in the List and Collection APIs.


    Q: Do you need to allow for this in your code?

    A: IMO is reasonable to write your code so that it works for "normal" lists. It is not possible to allow for all of the crazy things that a custom list class might do.