ArrayList源码分析(下)——Java8中新增的Spliterator的分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/starexplode/article/details/80567758

ArrayList源码分析(下)——从ArrayList中分析Java8新增的方法

从集合的最基本的接口Collection中可以看出Java8中新增了下面几点内容:
1. spliterator
2. stream
3. parallelStream

default Spliterator<E> spliterator() {
    return Spliterators.spliterator(this, 0);
}
default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}
default Stream<E> parallelStream() {
    return StreamSupport.stream(spliterator(), true);
}

1. spliterator

从源码中可以看出spiterator返回一个Spliterator对象。
Spliterator用于遍历和分隔一个对象中的元素,这个对象必须实现Spliterator接口,实现这个接口类有Collection,数组等。
Spliterator可以逐个的遍历元素,或者批量的遍历。
Spliterator是一个可以分割的迭代器,可以将Spilterator实例分割成多个小的Spilterator实例。
下面的是Spliterator中的一些特征值:

// 表示迭代器需要按照原始的顺序迭代器中的元素
    public static final int ORDERED    = 0x00000010;
    // 迭代器中的元素是没音重复的
    public static final int DISTINCT   = 0x00000001;
    // 按照某种排序方式的顺序迭代其中的元素
    public static final int SORTED     = 0x00000004;
    // 表示迭代器中的元素的个数是可计数的,有界的
    public static final int SIZED      = 0x00000040;
    // 迭代器中的元素是非空的
    public static final int NONNULL    = 0x00000100;
    // 迭代器中的元素是不可以改变的,不能增加也不能替换和删除。
    public static final int IMMUTABLE  = 0x00000400;
    // 表示迭代器的数据源是线程安全的`
    public static final int CONCURRENT = 0x00001000;
    // 表示当前的迭代器的所有的子迭代器(直接的或者间接的),都是'SIZED'和SUBSIZED的
    public static final int SUBSIZED = 0x00004000;
}

下面的是Spliterator中的一些方法:

public interface Spliterator<T> {
    // 如果有元素剩余,那么执行action,并返回true,如果没有元素剩余,返回false
    boolean tryAdvance(Consumer<? super T> action);
    // 对当前的线程中的元素执行给定的操作,直到所有的元素被处理或者抛出异常
    default void forEachRemaining(Consumer<? super T> action) {
        // 从这里也可以看出tryAdvance的用法
        do { } while (tryAdvance(action));
    }
    // 将一个Spliterator。分割的Spliterator可以被用于每个子线程进行处理,从而达到并发的效果
    Spliterator<T> trySplit();
    // 返回forEachRemain()需要遍历元素总数的估计值,如果这个结果是无穷大,未计数的,那么返回
    long estimateSize();
    // 如果当前线程是可以计算剩余元素的总数,那么返回剩余元素的总数,否则返回-1
    default long getExactSizeIfKnown() {
        // 这里利用了与、或运算,可以先看下面的
        return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
    }
    // 返回此Spliterator及其元素的一组特征值,这些结果表示为(ORDERED , DISTINCT , SORTED , SIZED ,  NONNULL , IMMUTABLE , CONCURRENT , SUBSIZED )的或运算
    // 如果符合该Spliterator有什么特性,那么代表那个属性的那一位就是1,否则就是0
    int characteristics();

    // Spliterator是否有执行的特性,
    // 这里同样使用了位运算的特性
    default boolean hasCharacteristics(int characteristics) {
        return (characteristics() & characteristics) == characteristics;
    }

    // 如果这个Spilterator的数据源是可排序的,如果数据源是自然排序,返回null。 如果数据源不是SORTED,则抛出IllegalStateException
    default Comparator<? super T> getComparator() {
        throw new IllegalStateException();
    }

下面的这个是Spliterator的一个内部接口,这个接口继承了Spliterator这个接口。

/**
 * @param <T> 此Spliterator的返回类型,该类型必须是原始类型的包装类型,如Integer的原始类型int类型
 * @param <T_CONS> 原始消费者类型Consumer,必须和T对应,例如Integer对应IntConsumer
 * @param <T_SPLITR> 原始的Spilterator。该类型和上面的一样,必须和T对应
 *  这么说可能还是不好理解,可以看下面的一个实现
 */
public interface OfPrimitive<T, T_CONS, T_SPLITR extends java.util.Spliterator.OfPrimit
        extends java.util.Spliterator<T> {
    @Override
    T_SPLITR trySplit();

    @SuppressWarnings("overloads")
    boolean tryAdvance(T_CONS action);

    @SuppressWarnings("overloads")
    default void forEachRemaining(T_CONS action) {
        do { } while (tryAdvance(action));
    }
}
public interface OfInt extends java.util.Spliterator.OfPrimitive<Integer, IntConsumer, java.util.Spliterato
    @Override
    OfInt trySplit();
    @Override
    boolean tryAdvance(IntConsumer action);
    @Override
    default void forEachRemaining(IntConsumer action) {
        do { } while (tryAdvance(action));
    }

    @Override
    default boolean tryAdvance(Consumer<? super Integer> action) {
        if (action instanceof IntConsumer) {
            return tryAdvance((IntConsumer) action);
        }
        else {
            if (Tripwire.ENABLED)   // 如果Boolea系统的属性org.openjdk.java.util.stream.tripwire设置为true
                Tripwire.trip(getClass(),   // 那么这里会出现警告
                        "{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
            return tryAdvance((IntConsumer) action::accept);
        }
    }

    @Override
    default void forEachRemaining(Consumer<? super Integer> action) {
        if (action instanceof IntConsumer) {
            forEachRemaining((IntConsumer) action);
        }
        else {
            if (Tripwire.ENABLED)
                Tripwire.trip(getClass(),
                        "{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
            forEachRemaining((IntConsumer) action::accept);
        }
    }
}

下面的这个是ArrayList中获取分割器的一个实现:

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

下面的就是ArrayList中的ArrayListSpliterator的实现:

/**
 * 基于索引的、二分的、懒加载器
 * Index-based split-by-two, lazily initialized Spliterator
 */
static final class ArrayListSpliterator<E> implements Spliterator<E> {

    // 用于存放ArrayList对象
    private final ArrayList<E> list;
    // 当前位置(包含),advance/spilt操作时会被修改
    private int index; // current index, modified on advance/split
    // 结束位置(不包含),-1表示到最后一个元素
    private int fence; // -1 until used; then one past last index
    // 用于存放list的modCount
    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;
        // 第一次初始化时,fence才会小于0
        if ((hi = fence) < 0) {
            // 如果集合中没有元素
            if ((lst = list) == null)
                hi = fence = 0;
            else {
                expectedModCount = lst.modCount;
                hi = fence = lst.size;
            }
        }
        return hi;
    }
    // 分割list,返回一个返回一个新分割出的spilterator实例
    // 相当于二分法,这个方法会递归
    // 1. ArrayListSpilterator本质还是对原list进行操作,只是通过index和fence来控制每次处理的范围
    public ArrayListSpliterator<E> trySplit() {
        // hi结束位置(不包括) lo:开始位置 mid中间位置
        int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
        // 当lo >= mid, 表示不能再分割
        // 当lo < mid时,表示可以分割,切割(lo, mid)出去,同时更新index = mid
        return (lo >= mid) ? null : // divide range in half unless too small
                new ArrayListSpliterator<E>(list, lo, index = mid,
                        expectedModCount);
    }
    /**
     * 返回true时,表示可能还有元素未处理
     * 返回falsa时,没有剩余元素处理了
     *
     * @param action
     * @return
     */
    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;
    }
    /**
     * 顺序遍历处理所有剩下的元素
     *
     * @param action
     */
    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();
        // 如果list不为空,且list中的元素不为空
        if ((lst = list) != null && (a = lst.elementData) != null) {
            // 当fence < 0 时,表示fence和exceptModCount未初始化
            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(e);
                }
                if (lst.modCount == mc)
                    return;
            }
        }
        throw new ConcurrentModificationException();
    }
    // 估算大小
    public long estimateSize() {
        return (long) (getFence() - index);
    }
    // 返回特征值
    public int characteristics() {
        return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
    }
}

猜你喜欢

转载自blog.csdn.net/starexplode/article/details/80567758
今日推荐