--- old/src/java.base/share/classes/java/util/ArrayList.java 2016-02-02 10:15:12.145394300 +0600 +++ new/src/java.base/share/classes/java/util/ArrayList.java 2016-02-02 10:15:11.918894300 +0600 @@ -1281,8 +1281,7 @@ public Spliterator spliterator() { checkForComodification(); - return new ArrayListSpliterator<>(ArrayList.this, offset, - offset + this.size, this.modCount); + return new ArrayListSpliterator(this, offset, -1, 0); } } @@ -1316,11 +1315,11 @@ */ @Override public Spliterator spliterator() { - return new ArrayListSpliterator<>(this, 0, -1, 0); + return new ArrayListSpliterator(null, 0, -1, 0); } /** Index-based split-by-two, lazily initialized Spliterator */ - static final class ArrayListSpliterator implements Spliterator { + final class ArrayListSpliterator implements Spliterator { /* * If ArrayLists were immutable, or structurally immutable (no @@ -1354,15 +1353,15 @@ * these streamlinings. */ - private final ArrayList list; + private final SubList subList; private int index; // current index, modified on advance/split private int fence; // -1 until used; then one past last index private int expectedModCount; // initialized when fence set /** Create new spliterator covering the given range */ - ArrayListSpliterator(ArrayList list, int origin, int fence, - int expectedModCount) { - this.list = list; // OK if null unless traversed + ArrayListSpliterator(SubList subList, int origin, + int fence, int expectedModCount) { + this.subList = subList; this.index = origin; this.fence = fence; this.expectedModCount = expectedModCount; @@ -1371,33 +1370,36 @@ private int getFence() { // initialize fence to size on first use int hi; // (a specialized variant appears in method forEach) ArrayList lst; + SubList subLst; if ((hi = fence) < 0) { - if ((lst = list) == null) - hi = fence = 0; - else { + if ((subLst = subList) == null) { + lst = ArrayList.this; expectedModCount = lst.modCount; hi = fence = lst.size; } + else { + expectedModCount = subLst.modCount; + hi = fence = subLst.offset + subLst.size; + } } return hi; } - public ArrayListSpliterator trySplit() { + public ArrayListSpliterator trySplit() { int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; return (lo >= mid) ? null : // divide range in half unless too small - new ArrayListSpliterator<>(list, lo, index = mid, + new ArrayListSpliterator(null, lo, index = mid, expectedModCount); } public boolean tryAdvance(Consumer action) { - if (action == null) - throw new NullPointerException(); + Objects.requireNonNull(action); int hi = getFence(), i = index; if (i < hi) { index = i + 1; - @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; + @SuppressWarnings("unchecked") E e = (E)elementData[i]; action.accept(e); - if (list.modCount != expectedModCount) + if (ArrayList.this.modCount != expectedModCount) throw new ConcurrentModificationException(); return true; } @@ -1405,14 +1407,21 @@ } public void forEachRemaining(Consumer action) { + Objects.requireNonNull(action); int i, hi, mc; // hoist accesses and checks from loop - ArrayList lst; Object[] a; - if (action == null) - throw new NullPointerException(); - if ((lst = list) != null && (a = lst.elementData) != null) { + ArrayList lst = ArrayList.this; + SubList subLst; + Object[] a; + if ((a = lst.elementData) != null) { if ((hi = fence) < 0) { - mc = lst.modCount; - hi = lst.size; + if ((subLst = subList) == null) { + mc = lst.modCount; + hi = lst.size; + } + else { + mc = subLst.modCount; + hi = subLst.offset + subLst.size; + } } else mc = expectedModCount; --- old/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java 2016-02-02 10:15:13.146894300 +0600 +++ new/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java 2016-02-02 10:15:12.916894300 +0600 @@ -120,8 +120,8 @@ } void addList(Function, ? extends List> l) { - // @@@ If collection is instance of List then add sub-list tests addCollection(l); + addCollection(l.andThen(list -> list.subList(0, list.size()))); } void addMap(Function, ? extends Map> mapConstructor) {