Spliterator接口

package java.util;

import java.util.function.Consumer; //函数接口
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;

//分割迭代器,分割io流,数组等,可以用于分治并发提高性能
public interface Spliterator<T> {
    // Consumer<? super T> action表示一个函数接口定义的函数
    // 如果还有元素存在,对下一个元素执行action
    boolean tryAdvance(Consumer<? super T> action);

    //在当前线程,串行对剩下所有的元素执行函数action
    default void forEachRemaining(Consumer<? super T> action){
        do { } while (tryAdvance(action));
    }

    //如果此 Spliterator 可以被分割,则会返回一个包含部分元素的 Spliterator,
    // 然后从此方法返回,从此方法返回的 Spliterator 中的元素,将从当前 Spliterator 中分离出去
    Spliterator<T> trySplit();

    //返回会被 forEachRemaining 操作的元素的数量的估算值,
    //若元素是无限的、未知的、或者是计算成本过高的,会返回一个最大值(MAX_VALUE)
    long estimateSize();

    //如果spliterator是sized的,就返回estimateSize的结果(这个是准确的数量),否则返回-1
    default long getExactSizeIfKnown(){
        return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
    }

    // 返回这个spliterator的元素的特征的集合。
    // 结果被表达成ORDERED,DISTINCT,SORTED,SIZED,NONNULL,IMMUTABLE,CONCURRENT,SUBSIZED的或值。
    // 在trySplit前或者两个trySplit之前重复调用characteristics应该总是返回相同的结果。
    // 如果一个spliterator报告一个不一致的特征集合(不管返回给一个调用或者多个调用),使用这个spliterator不能保证任何计算
    // 一个spliterator的特征在分割前和分割后可能不同。典型的例子是sized,subsized,concurrent
    int characteristics();

    // 如果这个spliterator包含了给定的所有特征,返回true
    default boolean hasCharacteristics(int characteristics){
        return (characteristics() & characteristics) == characteristics;
    }

    //    如果spliterator的来源是sorted,且通过一个comparator排序,则返回这个comparator。
    //    如果来源是sorted,以自然地顺序,返回null。
    //    然而,如果来源不是sorted,抛出IllegalStateException。
    default Comparator<? super T> getComparator(){
        throw new IllegalStateException();
    }

    // 特征值:代表着为元素定义了顺序。如果这样,spliterator保证trySplit严格地按照元素的前缀分割。
    // tryAdvance以前缀的顺序,一次前进一个元素。forEachRemaining以相遇的顺序执行操作。
    public static final int ORDERED = 0x00000010;

    //特征值:两两元素都不相同,基于set集合的分割迭代器
    public static final int DISTINCT = 0x00000001;

    //特征值:根据一个比较器定义了顺序
    public static final int SORTED = 0x00000004;

    //特征值:代表着在遍历或者分割前返回的estimateSize代表了一个有限的大小
    public static final int SIZED = 0x00000040;

    //特征值:代表着迭代器迭代过程中的元素不会null
    public static final int NONNULL = 0x00000100;

    //特征值:代表着迭代器的数据源不能改变(增删改)
    public static final int IMMUTABLE = 0x00000400;

    //特征值,代表着元素的来能可能被安全地,并发地修改,(允许增加,代替,和/或者删除)通过没有多余同步的多线程
    public static final int CONCURRENT = 0x00001000;

    // 特征值,代表着所有的通过trySplit产生的spliterator都是sized和subsized。
    // 这意味着所有的子spliterator,无论是亲的或者不亲的,都是sized的
    public static final int SUBSIZED = 0x00004000;

    //针对不同java数据类型设计的分割迭代器:重写方法意义同上**************************************************************//

    //内部接口 一个专门为基本类型的分割迭代器
    //     * @param <T> 被这个spliterator返回的元素的类型。这个类型必须是一个基本类型的包装类,例如Integer对于基本类型int。
    //     * @param <T_CONS> 原始的conumser的类型。这个类型必须是对T的consumer类的基本实例。例如IntConsumer对于Integer、
    //     * @param <T_SPLITR> 基本spliterator的类型。这个类型必须是对T的spliterator的基本实例,例如Spliterator.OfInt对于Integer
    //     * <p>这个类里重写了trySplit,返回T_SPLITR类型的spliterator。
    //     * <p>还增加了两个方法tryAdvance,forEachRemaining,里面的参数为T_CONS
    public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
            extends 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));
        }
    }

    //内部接口:为Integer提供的分割迭代器****************************************************************//
    public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {

        @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)
                    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);
            }
        }
    }

    //为 Long类型设计的分割迭代器*******************************************************//
    public interface OfLong extends OfPrimitive<Long, LongConsumer, OfLong> {

        @Override
        OfLong trySplit();

        @Override
        boolean tryAdvance(LongConsumer action);

        @Override
        default void forEachRemaining(LongConsumer action){
            do { } while (tryAdvance(action));
        }

        @Override
        default boolean tryAdvance(Consumer<? super Long> action){
            if(action instanceof LongConsumer){
                return tryAdvance((LongConsumer) action);
            }else{
                if(Tripwire.ENABLED)
                    Tripwire.trip(getClass(),
                                  "{0} calling Spliterator.OfLong.tryAdvance((LongConsumer) action::accept)");
                return tryAdvance((LongConsumer) action::accept);
            }
        }

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

    //为 Double 类型设计的分割迭代器*******************************************************//
    public interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> {

        @Override
        OfDouble trySplit();

        @Override
        boolean tryAdvance(DoubleConsumer action);

        @Override
        default void forEachRemaining(DoubleConsumer action){
            do { } while (tryAdvance(action));
        }

        @Override
        default boolean tryAdvance(Consumer<? super Double> action){
            if(action instanceof DoubleConsumer){
                return tryAdvance((DoubleConsumer) action);
            }else{
                if(Tripwire.ENABLED)
                    Tripwire.trip(getClass(),
                                  "{0} calling Spliterator.OfDouble.tryAdvance((DoubleConsumer) action::accept)");
                return tryAdvance((DoubleConsumer) action::accept);
            }
        }
        @Override
        default void forEachRemaining(Consumer<? super Double> action){
            if(action instanceof DoubleConsumer){
                forEachRemaining((DoubleConsumer) action);
            }else{
                if(Tripwire.ENABLED)
                    Tripwire.trip(getClass(),
                                  "{0} calling Spliterator.OfDouble.forEachRemaining((DoubleConsumer) action::accept)");
                forEachRemaining((DoubleConsumer) action::accept);
            }
        }
    }
}
Java之uitil包源码阅读 文章被收录于专栏

源码阅读是程序员必不可少的,本专栏记录本人阅读java源码笔记,与阅读此专栏的同道共同进步。 本专栏以字典序对源码进行阅读注释,主要工作:1.去除源码中冗长的英语注释,用简短的注释代替;2.对关键语句和算法予以说明。3.概要性描述。

全部评论

相关推荐

自从我室友在计算机导论课上听说了“刷&nbsp;LeetCode&nbsp;是进入大厂的敲门砖”,整个人就跟走火入魔了一样。他在宿舍门口贴了一张A4纸,上面写着:“正在&nbsp;DP,请勿打扰,否则&nbsp;Time&nbsp;Limit&nbsp;Exceeded。”日记本的扉页被他用黑色水笔加粗描了三遍:“Talk&nbsp;is&nbsp;cheap.&nbsp;Show&nbsp;me&nbsp;the&nbsp;code。”连宿舍聚餐,他都要给我们讲解:“今天的座位安排可以用回溯算法解决,但为了避免栈溢出,我建议用动态规划。来,这是状态转移方程:dp[i][j]&nbsp;代表第&nbsp;i&nbsp;个人坐在第&nbsp;j&nbsp;个位置的最优解。”我让他去楼下取个快递,他不直接去,非要在门口踱步,嘴里念念有词:“这是一个图的遍历问题。从宿舍楼(root)到驿站(target&nbsp;node),我应该用&nbsp;BFS&nbsp;还是&nbsp;DFS?嗯,求最短路径,还是广度优先好。”和同学约好出去开黑,他会提前发消息:“集合点&nbsp;(x,&nbsp;y),我们俩的路径有&nbsp;k&nbsp;个交点,为了最小化时间复杂度,应该在&nbsp;(x/2,&nbsp;y/2)&nbsp;处汇合。”有一次另一个室友低血糖犯了,让他帮忙找颗糖,他居然冷静地分析道:“别急,这是一个查找问题。零食箱是无序数组,暴力查找是&nbsp;O(n)。如果按甜度排序,我就可以用二分查找,时间复杂度降到&nbsp;O(log&nbsp;n)。”他做卫生也要讲究算法效率:“拖地是典型的岛屿问题,要先把连通的污渍区块都清理掉。倒垃圾可以用双指针法,一个指针从左往右,一个从右往左,能最快匹配垃圾分类。”现在我们宿舍的画风已经完全变了,大家不聊游戏和妹子,对话都是这样的:“你&nbsp;Two&nbsp;Sum&nbsp;刷了几遍了?”“别提了,昨天遇到一道&nbsp;Hard&nbsp;题,我连暴力解都想不出来,最后只能看题解。你呢?”“我动态规划还不行,总是找不到最优子结构。今天那道接雨水给我整麻了。”……LeetCode&nbsp;真的害了我室友!!!
老六f:编程嘉豪来了
AI时代还有必要刷lee...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务