< 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 >