On Mon, May 14, 2018 at 1:45 PM, Paul Sandoz <paul.san...@oracle.com> wrote:
> > > On May 14, 2018, at 12:43 PM, Martin Buchholz <marti...@google.com> wrote: > > > > On Mon, May 14, 2018 at 12:18 PM, Paul Sandoz <paul.san...@oracle.com> > wrote: > >> >>> A CME is not necessarily associated with just structural modifications >>> it could, on a best effort basis, be associated with any modification, >>> which is cheaper to do for bulk operations rather than individual >>> operations, and this operation can be used to perturb all the elements of >>> the list (just like sort) causing strange and hard to track bugs while in >>> the middle of iterating. IMHO its better to fail under such circumstances >>> rather than be silent. >>> >> >> It's tempting to treat modCount as a count of ALL modifications, >> especially given its name, but that's different from the historical >> behavior and design of these classes. Consistency with existing spec and >> implementations is the biggest argument. >> >> >> I mentally revised the history when doing the collections/stream API work >> since we added more bulk operations, since this is on a “best effort” basis >> and if it’s cheap to do then there is no real harm in it and it might help. >> >> > Spec says: > > """protected transient int modCount > > The number of times this list has been structurally modified. Structural > modifications are those that change the size of the list, or otherwise > perturb it in such a fashion that iterations in progress may yield > incorrect results.""" > > replaceAll doesn't qualify as a structural modification. > > > Why not? It can "perturb it in such a fashion that iterations in progress > may yield incorrect results”. > Why? It replaces every element "inplace" in the style of List.set(i) which is also not a structural modification. For ArrayList and Vector in particular, List.replaceAll is as safe as List.set(int). And if there was a List implementation for which that was not the case, it would probably be a bug in replaceAll implementation. Think ordinary array assignment or AtomicReferenceArray assignment.