zoukankan      html  css  js  c++  java
  • java基础-Steam[3]-Spliterator接口

    Spliterator接口

    Spliterator(splitable iterator可分割迭代器)接口是Java为了并行遍历数据源中的元素而设计的迭代器,这个可以类比最早Java提供的顺序遍历迭代器Iterator,但一个是顺序遍历,一个是并行遍历。

    public interface Spliterator<T> {
        // 如果还有元素存在,则执行action,并返回true,否则返回false
        boolean tryAdvance(Consumer<? super T> action);
    
        // 顺序对每个元素执行action,直到所有元素都被处理或者抛出异常
        default void forEachRemaining(Consumer<? super T> action) {
            do { } while (tryAdvance(action));
        }
        // 将原来 spliterator 进行分区,生成新的spliterator
        //firstSpliterator 包含[1,2,3,4,5],
        //secSpliterator = spliterator.trySplit()则可能返回包含[3,4,5]的spliterator
        //而firstSpliterator只保留[1,2]
        //这可以将原spliterator拆分为多个部分,以便并行同步处理
        //Spliterator如果包含无穷个元素,则trySplit()返回null
        Spliterator<T> trySplit();
    
        //返回将遇到的元素数量的估计值,如果无限,未知或计算成本太高,则返回Long.MAX_VALUE。
        //如果此Spliterator为SIZED且尚未部分遍历或拆分,或者此Spliterator已进行SUBSIZED且尚未部分遍历,则此估计值必须是完整遍历将遇到的元素的准确计数。否则,此估计值可能是任意不准确的,但必须按照trySplit()调用中指定的方式减少。
        long estimateSize();
    
        //Convenience method that returns {@link #estimateSize()} if this Spliterator is {@link #SIZED}, else {@code -1}.
        default long getExactSizeIfKnown() {
            return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
        }
    
        // 返回该Spliterator的特征值集合,ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT、SUBSIZED
        // 在trySplit调用之前或之间对给定spliterator上的characteristics()重复调用应始终返回相同的结果。
        int characteristics();
    
        //如果此Spliterator的characteristics()包含所有给定特性,则返回true,否则为false。
        default boolean hasCharacteristics(int characteristics) {
            return (characteristics() & characteristics) == characteristics;
        }
    
        // 如果此Spliterator的源由Comparator比较器为SORTED,则返回该Comparator。如果源按Comparable自然顺序为SORTED,则返回null。否则,如果源不是SORTED,则抛出IllegalStateException。
        default Comparator<? super T> getComparator() {
            throw new IllegalStateException();
        }
    }
    

    Spliterator示例

    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Spliterator<Integer> firstSpliterator = stream.spliterator();
        Spliterator<Integer> secondSpliterator = firstSpliterator.trySplit();
        Spliterator<Integer> thirdSpliterator = firstSpliterator.trySplit();
        System.out.println("firstSpliterator");
        while (firstSpliterator.tryAdvance(n -> System.out.println("first =>" + n))) {
    
        }
        System.out.println("secondSpliterator");
        while (secondSpliterator.tryAdvance(n -> System.out.println("second =>" + n))) {
    
        }
        System.out.println("thirdSpliterator");
        while (thirdSpliterator.tryAdvance(n -> System.out.println("third =>" + n))) {
    
        }
    }
    firstSpliterator
    first =>7
    first =>8
    first =>9
    secondSpliterator
    second =>1
    second =>2
    second =>3
    second =>4
    thirdSpliterator
    third =>5
    third =>6
    

    ArrayList

    public Spliterator<E> spliterator() {
    	return new ArrayListSpliterator(0, -1, 0);
    }
    
    final class ArrayListSpliterator implements Spliterator<E> {
    
    
        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
    
        /** Creates new spliterator covering the given range. */
        ArrayListSpliterator(int origin, int fence, int expectedModCount) {
            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)
            if ((hi = fence) < 0) {
                expectedModCount = modCount;
                hi = fence = 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(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)elementData[i];
                action.accept(e);
                if (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
            Object[] a;
            if (action == null)
                throw new NullPointerException();
            if ((a = elementData) != null) {
                if ((hi = fence) < 0) {
                    mc = modCount;
                    hi = 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 (modCount == mc)
                        return;
                }
            }
            throw new ConcurrentModificationException();
        }
    
        public long estimateSize() {
            return getFence() - index;
        }
    
        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }
    

    参考

    1. Java8中Spliterator详解
  • 相关阅读:
    Red Black Tree 红黑树 AVL trees 2-3 trees 2-3-4 trees B-trees Red-black trees Balanced search tree 平衡搜索树
    Red Black Tree java.util.TreeSet
    finding friends with mapreduce
    zabbix 监控jmx 需要--enable-java
    zabbix 监控jmx 需要--enable-java
    zabbix 监控jvm
    zabbix 监控jvm
    eval 捕获dbi错误
    eval 捕获dbi错误
    eval 捕获错误
  • 原文地址:https://www.cnblogs.com/froggengo/p/14675972.html
Copyright © 2011-2022 走看看