Spliterator 接口 源码解析

407 阅读1分钟

Spliterator 定义的方法

图片.png

接口中定义的常量图

图片.png

ArrayList 中 ArrayListSpliterator 源码分析

@Override
public Spliterator<E> spliterator() {
    return new ArrayListSpliterator<>(this, 0, -1, 0);
}

static final class ArrayListSpliterator<E> implements Spliterator<E> {
    //用于存放ArrayList对象
   private final ArrayList<E> list;
   //起始位置(包含),advance/split操作时会修改
   private int index; 
   //结束位置(不包含),-1 表示到最后一个元素
   private int fence; 
   //用于存放list的modCount
   private int expectedModCount; 

   ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
                             int expectedModCount) {
            this.list = list; 
            this.index = origin;
            this.fence = fence;
            this.expectedModCount = expectedModCount;
        }
    //获取结束位置(存在意义:首次初始化石需对fence和expectedModCount进行赋值)
   private int getFence() { 
        int hi; 
        ArrayList<E> lst;
        //fence<0时(第一次初始化时,fence才会小于0):
        if ((hi = fence) < 0) {
            //list 为 null时,fence=0
            if ((lst = list) == null)
                hi = fence = 0;
            else {
            //否则,fence = list的长度。
                expectedModCount = lst.modCount;
                hi = fence = lst.size;
            }
        }
        return hi;
    }
    //分割list,返回一个新分割出的spliterator实例
    public ArrayListSpliterator<E> trySplit() {
        //hi为当前的结束位置
        //lo 为起始位置
        //计算中间的位置
        int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
        //当lo>=mid,表示不能在分割,返回null
        //当lo<mid时,可分割,切割(lo,mid)出去,同时更新index=mid
        return (lo >= mid) ? null : 
            new ArrayListSpliterator<E>(list, lo, index = mid,                                         expectedModCount);
    }
    //返回true 时,只表示可能还有元素未处理
    //返回false 时,没有剩余元素处理了。。。
    public boolean tryAdvance(Consumer<? super E> action) {
         if (action == null)
             throw new NullPointerException();
         //hi为当前的结束位置
         //i 为起始位置
         int hi = getFence(), i = index;
         //还有剩余元素未处理时
         if (i < hi) {
             //处理i位置,index+1
             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) {
           //当fence<0时,表示fence和expectedModCount未初始化,可以思考一下这里能否直接调用getFence(),嘿嘿?
           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];
                   //调用action.accept处理元素
                   action.accept(e);
               }
               //遍历时发生结构变更时抛出异常
               if (lst.modCount == mc)
                   return;
           }
       }
       throw new ConcurrentModificationException();
   }

   // 还剩多少个元素没有遍历
   public long estimateSize() {
        return (long) (getFence() - index);
    }

   // 3个常量和
    public int characteristics() {
        //打上特征值:、可以返回size
        return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
    }
}

实现类图

图片.png