On Jan 7, 2015, at 11:56 AM, Chris Hegarty <chris.hega...@oracle.com> wrote:
> On 07/01/15 10:47, Daniel Fuchs wrote: >> On 07/01/15 11:31, Paul Sandoz wrote: >>> >>> On Jan 7, 2015, at 10:45 AM, Remi Forax <fo...@univ-mlv.fr> wrote: >>> >>>> A simple Java question, what this code does ? >>>> >>>> ArrayList<String> list = new ArrayList<>(); >>>> list.add("foo"); >>>> list.add("bar"); >>>> for(String s: list) { >>>> list.remove(s); >>>> } >>>> >>>> :( >>>> >>> >>> We could improve the best-effort basis by which >>> ConcurrentModificationException is thrown by snapshotting the >>> collection size on construction of the iterator > > This was my thought too. > > diff --git a/src/java.base/share/classes/java/util/ArrayList.java > b/src/java.base/share/classes/java/util/ArrayList.java > --- a/src/java.base/share/classes/java/util/ArrayList.java > +++ b/src/java.base/share/classes/java/util/ArrayList.java > @@ -853,9 +853,10 @@ > int cursor; // index of next element to return > int lastRet = -1; // index of last element returned; -1 if no such > int expectedModCount = modCount; > + int itrSize = size; > > public boolean hasNext() { > - return cursor != size; > + return cursor != itrSize; > } > > @SuppressWarnings("unchecked") > @@ -881,6 +882,7 @@ > cursor = lastRet; > lastRet = -1; > expectedModCount = modCount; > + itrSize--; > } catch (IndexOutOfBoundsException ex) { > throw new ConcurrentModificationException(); > } > @@ -909,7 +911,7 @@ > } > > final void checkForComodification() { > - if (modCount != expectedModCount) > + if (modCount != expectedModCount || size != itrSize) > throw new ConcurrentModificationException(); > } > } > Under what conditions can the mod count be the same but the size is different? Would this not indicate there was a bug in some other method that made a structural change but did not update the mod count? Same apples to this: Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); (Note as per usual in these discussions i am not referring to concurrent operation from multiple threads, under such conditions all bets are off.) Unfortunately the change history in openjdk only goes back so far, and i agree with Doug that there might be some reason why this change was not made earlier on (it seems like an "obvious" thing to do). Paul.