< prev index next >

src/java.base/share/classes/java/util/ArrayList.java

Print this page

        

*** 1279,1290 **** throw new ConcurrentModificationException(); } public Spliterator<E> spliterator() { checkForComodification(); ! return new ArrayListSpliterator<>(ArrayList.this, offset, ! offset + this.size, this.modCount); } } @Override public void forEach(Consumer<? super E> action) { --- 1279,1289 ---- throw new ConcurrentModificationException(); } public Spliterator<E> spliterator() { checkForComodification(); ! return new ArrayListSpliterator(this, offset, -1, 0); } } @Override public void forEach(Consumer<? super E> action) {
*** 1314,1328 **** * @return a {@code Spliterator} over the elements in this list * @since 1.8 */ @Override public Spliterator<E> spliterator() { ! return new ArrayListSpliterator<>(this, 0, -1, 0); } /** Index-based split-by-two, lazily initialized Spliterator */ ! static final class ArrayListSpliterator<E> implements Spliterator<E> { /* * If ArrayLists were immutable, or structurally immutable (no * adds, removes, etc), we could implement their spliterators * with Arrays.spliterator. Instead we detect as much --- 1313,1327 ---- * @return a {@code Spliterator} over the elements in this list * @since 1.8 */ @Override public Spliterator<E> spliterator() { ! return new ArrayListSpliterator(null, 0, -1, 0); } /** Index-based split-by-two, lazily initialized Spliterator */ ! final class ArrayListSpliterator implements Spliterator<E> { /* * If ArrayLists were immutable, or structurally immutable (no * adds, removes, etc), we could implement their spliterators * with Arrays.spliterator. Instead we detect as much
*** 1352,1421 **** * occur anywhere other than inside forEach itself. The other * less-often-used methods cannot take advantage of most of * these streamlinings. */ ! private final ArrayList<E> list; 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<E> list, int origin, int fence, ! int expectedModCount) { ! this.list = list; // OK if null unless traversed this.index = origin; this.fence = fence; this.expectedModCount = expectedModCount; } private int getFence() { // initialize fence to size on first use int hi; // (a specialized variant appears in method forEach) ArrayList<E> lst; if ((hi = fence) < 0) { ! if ((lst = list) == null) ! hi = fence = 0; ! else { expectedModCount = lst.modCount; hi = fence = lst.size; } } return hi; } ! public ArrayListSpliterator<E> 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, expectedModCount); } public boolean tryAdvance(Consumer<? super E> action) { ! if (action == null) ! throw new NullPointerException(); int hi = getFence(), i = index; if (i < hi) { index = i + 1; ! @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; action.accept(e); ! if (list.modCount != expectedModCount) throw new ConcurrentModificationException(); return true; } return false; } public void forEachRemaining(Consumer<? super E> action) { int i, hi, mc; // hoist accesses and checks from loop ! ArrayList<E> lst; Object[] a; ! if (action == null) ! throw new NullPointerException(); ! if ((lst = list) != null && (a = lst.elementData) != null) { if ((hi = fence) < 0) { mc = lst.modCount; hi = lst.size; } else mc = expectedModCount; if ((i = index) >= 0 && (index = hi) <= a.length) { for (; i < hi; ++i) { @SuppressWarnings("unchecked") E e = (E) a[i]; --- 1351,1430 ---- * occur anywhere other than inside forEach itself. The other * less-often-used methods cannot take advantage of most of * these streamlinings. */ ! 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(SubList subList, int origin, ! int fence, int expectedModCount) { ! this.subList = subList; this.index = origin; this.fence = fence; this.expectedModCount = expectedModCount; } private int getFence() { // initialize fence to size on first use int hi; // (a specialized variant appears in method forEach) ArrayList<E> lst; + SubList subLst; if ((hi = fence) < 0) { ! 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() { int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; return (lo >= mid) ? null : // divide range in half unless too small ! new ArrayListSpliterator(null, lo, index = mid, expectedModCount); } public boolean tryAdvance(Consumer<? super E> action) { ! Objects.requireNonNull(action); int hi = getFence(), i = index; if (i < hi) { index = i + 1; ! @SuppressWarnings("unchecked") E e = (E)elementData[i]; action.accept(e); ! if (ArrayList.this.modCount != expectedModCount) throw new ConcurrentModificationException(); return true; } return false; } public void forEachRemaining(Consumer<? super E> action) { + Objects.requireNonNull(action); int i, hi, mc; // hoist accesses and checks from loop ! ArrayList<E> lst = ArrayList.this; ! SubList subLst; ! Object[] a; ! if ((a = lst.elementData) != null) { if ((hi = fence) < 0) { + if ((subLst = subList) == null) { mc = lst.modCount; hi = lst.size; } + else { + mc = subLst.modCount; + hi = subLst.offset + subLst.size; + } + } else mc = expectedModCount; if ((i = index) >= 0 && (index = hi) <= a.length) { for (; i < hi; ++i) { @SuppressWarnings("unchecked") E e = (E) a[i];
< prev index next >