< prev index next >
src/java.base/share/classes/java/util/ArrayList.java
Print this page
@@ -1279,12 +1279,11 @@
throw new ConcurrentModificationException();
}
public Spliterator<E> spliterator() {
checkForComodification();
- return new ArrayListSpliterator<>(ArrayList.this, offset,
- offset + this.size, this.modCount);
+ return new ArrayListSpliterator(this, offset, -1, 0);
}
}
@Override
public void forEach(Consumer<? super E> action) {
@@ -1314,15 +1313,15 @@
* @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);
+ return new ArrayListSpliterator(null, 0, -1, 0);
}
/** Index-based split-by-two, lazily initialized Spliterator */
- static final class ArrayListSpliterator<E> implements Spliterator<E> {
+ 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,70 +1351,80 @@
* 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 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<E> 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;
}
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 ((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<E> 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<? super E> 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;
}
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; Object[] a;
- if (action == null)
- throw new NullPointerException();
- if ((lst = list) != null && (a = lst.elementData) != null) {
+ 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 >