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