lambda表达式:Collection创建流,Stream,Spliterator,ReferencePipeline,AbstractPipeline源码分析

AutoCloseable

在这里插入图片描述

doc

一个对象,它可以保存资源(如文件或套接字句柄)直到它被关闭。当退出已在资源规范头中声明对象的try with resources块时,将自动调用自动关闭对象的close()方法。这种结构确保了及时发布,避免了资源耗尽异常和可能发生的错误。

实例


public class AutoCloseableTest implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println("关闭数据");
    }

    public static void main(String[] args) throws Exception {
        //此时程序执行完会自动调用AutoCloseableTest该方法执行代码块
        try(AutoCloseableTest test = new AutoCloseableTest()) {
            System.out.println("数据执行");
        }
    }
}
/*
	数据执行
	关闭数据
*/

BaseStream

在这里插入图片描述

在这里插入图片描述
也就是说 Stream流返回的类型是BaseStream中新的返回流类型

    /**
    	返回此流元素的迭代器。
     */
    Iterator<T> iterator();

    /**
     	返回此流元素的分隔迭代器。
     	这是流的终止操作
     */
    Spliterator<T> spliterator();

      /**
     	返回如果要执行终端操作,此流是否将并行执行。
     	调用流的终止操作方法后,调用此方法可能会产生不可预测的结果。
     	(意思我们使用时的在流的终止操作之前使用它)
     */
    boolean isParallel();

	/**
     返回一个的等价的串行流。可能返回自身,原因可能是流已经是串行的,
     也可能是基础流状态被修改为串行流(串行和并行方法 调用多次返回最后那个那个流)
     这是一个中间操作
     */
    S sequential();

   /*
	返回的等价并行流。可能会返回自身,原因可能已经是并行流,
	也可能是基础流状态已修改为并行流
	 这是一个中间操作
	*/
    S parallel();

 	/*
	返回未排序的等效流。可能会返回自身,原因可能是流已无序,
	也可能是基础流状态已修改为无序。
	这是一个中间操作
	*/
    S unordered();

    /*
返回具有附加关闭处理程序的等效流。Close处理程序在对流调用Close()方法时运行,并按添加顺序执行。
所有onClose程序都将会运行,即使以前的关闭处理程序引发异常。如果任何close处理程序抛出异常,
则抛出的第一个异常返回给close()的调用方,
而该异常中添加的任何剩余异常都将作为抑制异常(除非剩余异常之一与第一个异常是同一个异常,
因为异常无法抑制自身)返回自身。
	*/
    S onClose(Runnable closeHandler);

    /**
   	关闭此流,导致调用此流管道的所有关闭处理程序
     */
    @Override
    void close();

onClose示例

public class StreamTest2 {
    public static void main(String[] args) {


        List<String> list = Arrays.asList("hello", "nihao", "你好");
        /*
            onClose会在 close方法调用后去执行
         */
        try (Stream<String> stream = list.stream()) {
            stream.onClose(() -> {
                System.out.println("aaa");
            }).onClose(() -> {
                System.out.println("bbb");  
            }).forEach(System.out::println);
        }
    }


}
/*
hello
nihao
你好
aaa
bbb
*/

抛出1个异常

在这里插入图片描述

抛出2个不同异常

在这里插入图片描述

抛出相同异常

在这里插入图片描述
在这里插入图片描述

Stream方法源码解析

doc节选(重要)

  • 为了执行计算,流操作被组合成流管道。流管道由(可能是数组、集合、生成器函数、I/O通道等)、零个或多个中间操作(将流转换为另一个流,如筛选器(谓词))和终端操作(产生结果或副作用,如count()或forEach(Consumer))组成。流是惰性的;只有在启动终端操作时才对源数据执行计算,并且仅根据需要使用源元素
  • 大多数流操作接受描述用户指定行为的参数为了保持正确的行为,这些行为参数:必须是无干扰的(它们不会修改流源)以及在大多数情况下必须是无状态的(它们的结果不应该依赖于流管道执行期间可能更改的任何状态,类似操作同一种行为每个流元素执行顺序不同造成结果不同)
  • 这些参数总是函数接口(如函数)的实例,通常是lambda表达式或方法引用。除非另有规定,否则这些参数必须为非空
  • 一个流只能操作一次(调用中间或终端流操作)
  • Streams有一个close()方法并实现了AutoCloseable,但实际上几乎所有的stream实例在使用后都不需要关闭。
  • 流管道可以按串行执行,也可以并行执行。此执行模式是流的属性。流是通过串行或并行执行的初始选择创建的。(例如,集合.stream()创建顺序流,并且Collection.parallelStream集合(创建一个并行的)此执行模式的选择可以由sequential()(串行)或parallel()(并行同时使用以后面的为主)方法修改,也可以使用isParallel()方法查询
    在这里插入图片描述
  • 集合和流,虽然有一些表面上的相似之处,但有不同的目标。集合主要涉及对其元素的有效管理(增删改)和访问。相比之下,流不提供直接访问或操作其元素的方法,而是涉及声明性地描述其源和将在该源上聚合执行的计算操作。但是,如果提供的流操作没有提供所需的功能,则可以使用iterator()和spliterator()操作来执行受控遍历。
/*
	  Stream.of("one", "two", "three", "four")
     *         .filter(e -> e.length() > 3)
     *         .peek(e -> System.out.println("Filtered value: " + e))
     *         .map(String::toUpperCase)
     *         .peek(e -> System.out.println("Mapped value: " + e))
     *         .collect(Collectors.toList());
    对元素属性进行处理消费,同时返回流 (系统自动返回Consumer无返回值)
*/
Stream<T> peek(Consumer<? super T> action);

示例

public class StreamTest3 {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("nihao", "hello", "你好");

        //没有中间操作执行流程
//        list.stream().forEach(System.out::println);

        //存在中间操作执行流程
        list.stream().map(x -> x + ",").filter(x -> true).forEach(System.out::println);

    }
}


Collection.stream

/*
	返回以该集合为源的串行流。此时上例list.stream() 调用结束
	当spliterator()方法无法返回不可变、并发或延迟绑定的spliterator时,应重写此方法。(有关详细信息,请参见拆分器()。)
	{(后续调用方法看下分析)
*/
 default Stream<E> stream() 
        return StreamSupport.stream(spliterator(), false);
    }
  // 调用改方法返回迭代器 将集合和 特性传递过去
  @Override
   default Spliterator<E> spliterator() {
       return Spliterators.spliterator(this, 0);
   }

在这里插入图片描述
辅助类
在这里插入图片描述
在这里插入图片描述

Spliterator分割迭代器

Spliterators实现重新了


/*
	如果有剩余元素存在,则对其执行给定行为,返回true;否则返回false。
	如果这个分拆器被命令,则在遇到顺序中的下一个元素上执行动作。操作引发的异常将中继到调用方。
	(判断有没有下一个元素有执行下一个动作)
*/
 boolean tryAdvance(Consumer<? super T> action);

   /**
    对当前线程中的每个剩余元素按串行执行给定的操作,
    直到处理完所有元素或操作引发异常。如果此拆分器已排序,
    则按遇到顺序执行操作。操作引发的异常将中继到调用方。
     */
    default void forEachRemaining(Consumer<? super T> action) {
   		//对剩余元素执行了操作返回 Boolean值
        do { } while (tryAdvance(action));
    }
	/*
	如果此分隔器可以被分隔的,则返回一个涵盖元素的分隔迭代器,
	此分割迭代器在从该方法返回时将不被此分割迭代器涵盖。
	(就是被分割出来的元素存储到返回的分割迭代器,剩余的继续存到当前的分隔迭代器当中)

	如果此拆分器已ORDERED排序,则返回的拆分器必须包含元素也应该排序
	
    除非此拆分器包含无限多个元素,否则对trySplit()的重复调用最终结果必须返回null(无法进一步分隔)。
    返回值不为null时:
    	分隔前为estimateSize()报告的值在拆分后必须大于或等于当前分隔器和返回的分隔器的
    	estimateSize();以及

		如果此分隔器是SUBSIZED,则拆分前此分隔器的estimateSize()必须等于此分隔器的
		estimateSize()和分隔后返回的分隔器的总和
		A=T+newA

	此方法可能因任何原因返回null,包括空性、开始遍历后无法拆分、数据结构约束和效率考虑。

	理想的trySplit方法有效地(无遍历)将元素精确地分成两半,允许平衡的并行计算。此时并行
	计算效率最高,当分隔的极度不平衡时此时并行效率最低
	
	*/
	Spliterator<T> trySplit();
	
	/*
		返回forEachRemaining遍历将遇到的元素数的估计值,
		或返回Long.MAX_值(如果是无限的,未知的,或者计算成本太高而无法计算。)

		如果此分隔器已固定大小SIZED且尚未部分遍历或拆分,
		或者此分隔器已子化SUBSIZED且尚未部分遍历,
		则此估算值一定是遇到的元素的精确计数值。
		如果不满足上面调价,这个估计可能是任意不准确的,
		但必须在调用trySplit时减少。
	*/
	long estimateSize();
	
	/*
		如果此分割器已调整大小,则返回estimateSize()的便利方法,否则返回-1。
	*/
	default long getExactSizeIfKnown() {
        return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
    }
	
	/*
	返回分割器的特性值
	*/
   int characteristics();
	
	/*
		判断是否包含传过来的特性值
	*/
	default boolean hasCharacteristics(int characteristics) {
        return (characteristics() & characteristics) == characteristics;
    }
	/*
	如果此拆分器的源由比较器排序,则返回该比较器。
	如果源按自然顺序排序,则返回null。
	否则,如果源未排序,则抛出IllegalStateException。
	*/
	default Comparator<? super T> getComparator() {
        throw new IllegalStateException();
    }
	
	//有序
	public static final int ORDERED    = 0x00000010;
	//不同
	public static final int DISTINCT   = 0x00000001;
	//排序
	public static final int SORTED     = 0x00000004;
	/*
		确定大小
		特征值,表示在遍历或拆分之前从estimateSize()返回的值表示在没有结构源修改的情况下,
		表示完整遍历将遇到的元素数的精确计数的有限大小。
	*/
	public static final int SIZED      = 0x00000040;
	//不为空的
	public static final int NONNULL    = 0x00000100;
	/*
	不可变的
	特征值,表示不能在结构上修改元素源;
	也就是说,不能添加、替换或删除元素,因此在遍历期间不能发生此类更改。
	如果在遍历期间被修改则会抛出ConcurrentModificationException
	*/
	public static final int IMMUTABLE  = 0x00000400;
	//并发的
	public static final int CONCURRENT = 0x00001000;
	//元素分割完确定大小的
	public static final int SUBSIZED = 0x00004000;

/**
	
*/




Spliterator.OfPrimitive 内部接口

专门针对于原生值类型(Int Long Double)的迭代器。主要起到中介的作用
在这里插入图片描述

Spliterator.OfInt 内部接口

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

        /**
       		实现的是顶层Spliterator的tryAdvance方法
         */
        @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) {
        //action 可能传递 行为 也有可能传递Consumer对象(面向对象)
            if (action instanceof IntConsumer) {
            	//如果传递的是IntConsumer实例可以直接转换成对象
                forEachRemaining((IntConsumer) action);
            }
            else {
                if (Tripwire.ENABLED)
                    Tripwire.trip(getClass(),
                                  "{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
                 //如果不是传他的方法引用
                forEachRemaining((IntConsumer) action::accept);
            }
        }
    }
   //类似上
 @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);
            }
        }

public class ConsumerTest {

    public void test(Consumer<Integer> consumer) {
        consumer.accept(1000);
    }

    public static void main(String[] args) {
        ConsumerTest consumerTest = new ConsumerTest();

        Consumer<Integer> consumer = x -> System.out.println(x);
        IntConsumer intConsumer = x -> System.out.println(x);

        System.out.println(consumer instanceof Consumer);//true
        System.out.println(intConsumer instanceof Consumer);//false

        consumerTest.test(consumer);//面向对象的方式传递
        consumerTest.test((Consumer) intConsumer);//此时会报错


        consumerTest.test(intConsumer::accept);//将行为传递过去了 函数式方式

    }
}

Spliterators工厂类

//内部类
 static class IteratorSpliterator<T> implements Spliterator<T> {
 static final int BATCH_UNIT = 1 << 10;  // batch array size increment
        static final int MAX_BATCH = 1 << 25;  // max batch array size;
        private final Collection<? extends T> collection; // null OK
        private Iterator<? extends T> it; //collection集合的迭代器
        private final int characteristics; //特性值
        private long est;             // 估算的大小
        private int batch;            // 分批拆的大小
        	
     //
    public IteratorSpliterator(Collection<? extends T> collection, int characteristics) {
            //集合创建流是传过来的collection存储到内部类
            this.collection = collection;
            //此时刚调用时定义的迭代器为null
            this.it = null;
            //存储特性值
            this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
                                   ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
                                   : characteristics;
        }
        
 @Override
        public void forEachRemaining(Consumer<? super T> action) {
       		//传过来的集合不能为空
            if (action == null) throw new NullPointerException();
            //定义个迭代器
            Iterator<? extends T> i;
            //判断内部类定义的迭代器是否为空
            if ((i = it) == null) {
                i = it = collection.iterator();
                //设置分隔迭代器的大小估值
                est = (long)collection.size(); 
            }
            //调用Iterator迭代器的默认方法forEachRemaining 执行action行为
            i.forEachRemaining(action);
        }

ReferencePipeline引用管道(重要)

doc

中间管道阶段或管道源阶段实现的抽象基类(将流的源和中间操作统一在一个类),其元素为U类型。

  • ReferencePipeline表示流的源阶段与中间阶段
  • ReferencePipeline.Head表示流的源阶段
  • 二者在大部分属性的设定上都是类似的,但存在一些属性是不同的,比如说Head是没有previousStage的,而ReferencePipeline则存在等等

在这里插入图片描述

	/*
		流管道头(源)的构造函数。
	*/
   ReferencePipeline(Spliterator<?> source,
                      int sourceFlags, boolean parallel) {
            //AbstractPipeline构造方法进行构造
        super(source, sourceFlags, parallel);
    }
  /**
     *用于将中间操作附加到现有管道的构造函数。
     (流的串联)
     *
     * @param upstream the upstream element source.
     */
    ReferencePipeline(AbstractPipeline<?, P_IN, ?> upstream, int opFlags) {
        super(upstream, opFlags);
    }
   	 
 // Optimized sequential terminal operations for the head of the pipeline
		//他是针对优化串行管道源的终止操作(就是stream()之后进行操作无中间操作时)
        @Override
        public void forEach(Consumer<? super E_OUT> action) {
        	//!isParallel  也就是是串行时
            if (!isParallel()) {
           		/*
           		调用源分割器的的forEachRemaining方法执行每个流数据
				此时需要操作的数据已经在源分割迭代器当中
				*/
                sourceStageSpliterator().forEachRemaining(action);
            }
            else {//执行一般操作
                super.forEach(action);
            }
        }
	/*
	map的实现方法
	*/
	 @Override
    @SuppressWarnings("unchecked")
    public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) {
        Objects.requireNonNull(mapper);
        //创建一个无状态的中间阶段将其追加到上游管道上
        return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
            @Override
            Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
            /*
			Sink实例用于表示此管道的每个阶段 (具体阅读doc)
			向下游发送值时必须调用accept(int)方法
			而Sink 在接收参数时先发调用bigin方法 
			accept方法执行完 必须调用end方法

			Sink.ChainedReference创建一个链接引用 此时已经将
			begin、end和cancellationRequested方法连接到下游接收器
			此时下游自动执行连接引用方法(begin ,end) 当方法accept执行完直接
			自动调用down方法
			*/
                return new Sink.ChainedReference<P_OUT, R>(sink) {
                    @Override
                 
                    public void accept(P_OUT u) {
                    	//此时才是执行的真正操作 操作当前生成的元素值
                    	//同时调用downstream下游的行为
                    	//其他中间操作类似
                        downstream.accept(mapper.apply(u));
                    }
                };
            }
        };
    }

   /**
     * 通过将无状态中间操作附加到现有流来构造新流。
     *
     * @param <E_IN> 上游源中的元素类型
     * @param <E_OUT> 本阶段生产的元素类型
     * @since 1.8
     */
    abstract static class StatelessOp<E_IN, E_OUT>
            extends ReferencePipeline<E_IN, E_OUT> {
        /**
          通过将无状态中间操作附加到现有流来构造新流。
         *
         * @param upstream 上游管道阶段
         * @param inputShape 上游管道的结果类型
         * @param opFlags 新阶段的操作标志
         */
        StatelessOp(AbstractPipeline<?, E_IN, ?> upstream,
                    StreamShape inputShape,
                    int opFlags) {
            super(upstream, opFlags);
            //断言 上游的结果 一定要等于当前输入的结果类型
            assert upstream.getOutputShape() == inputShape;
        }

        @Override
        final boolean opIsStateful() {
            return false;
        }
    }

ReferencePipeline.Head<E_IN,E_OUT>

源阶段
E_IN:上游阶段源元素类型
E_OUT:当前阶段生成的元素类型

在这里插入图片描述

 static class Head<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> {
       
        Head(Supplier<? extends Spliterator<?>> source,
             int sourceFlags, boolean parallel) {
            super(source, sourceFlags, parallel);
        }

        /**
         * 源阶段的构造方法
         * source: 源数据
         * sourceFlags: 流的特性值
         * parallel:
         */
        Head(Spliterator<?> source,
             int sourceFlags, boolean parallel) {
             //调用ReferencePipeline的构造方法 构造源
            super(source, sourceFlags, parallel);
        }

        @Override
        final boolean opIsStateful() {
            throw new UnsupportedOperationException();
        }

        @Override
        final Sink<E_IN> opWrapSink(int flags, Sink<E_OUT> sink) {
            throw new UnsupportedOperationException();
        }

       

AbstractPipeline抽象管道

在这里插入图片描述
E_IN:上游阶段源元素类型
E_OUT:当前阶段生成的元素类型
S:实现BaseStream的接口类型

doc

  • “管道”类的抽象基类,它是流接口及其原始特化(IntStream)的核心实现。管理流管道的构建和计算。
  • AbstractPipeline表示流管道的初始部分,封装流源和零个或多个中间操作。各个抽象管道对象通常称为阶段,每个阶段描述是流源或中间操作
  • 在链接一个新的中间操作或执行一个终端操作之后,流被认为是被消费的,并且在这个流实例上不允许再进行中间或终端操作
  • 具体的中间阶段通常是从抽象管道、特化管道类(例如,IntPipeline)和扩展它的特定于操作的具体类构建的。AbstractPipeline包含了计算管道的大多数机制,并实现了操作的使用的方法;特定于的原生类添加了辅助方法,用于将结果收集到相应的特化的容器中。
  • 对于串行流和没有状态中间操作的并行流,并行流的管道计算是在一次传递中完成的,它“阻塞”了所有的操作。(就是每个元素执行了所有的中间操作再去执行下一个,当中间为假就不会往下执行
  • 对于具有状态操作的并行流,执行被划分为多个段,其中每个状态操作标记一个段的结束,每个段单独计算并将结果用作下一个段的输入。在所有情况下,在终端操作开始之前不会使用源数据

类的一些重要方法和属性


   /**
     反向链接到管道链的头部(如果这是源级,则为自己)
    ( 一般就是通过这个去链接源头跟中间操作)
     */
    @SuppressWarnings("rawtypes")
    private final AbstractPipeline sourceStage;

    /**
     *“上游”管道,如果这是源阶段,则为空。
     */
    @SuppressWarnings("rawtypes")
    private final AbstractPipeline previousStage;
    
     /**
    源分隔迭代器(此时集合数据已经存在到迭代器的一个常量属性当中)。仅对总管有效。
    在使用管道之前,如果非空,则sourceSupplier必须为空。
    在使用管道之后,如果非空,则设置为空(流已经被消费无法被使用)。
    sourceSpliterator与sourceSupplier 是互斥只能一个为空
    两个必须的又一个为非空 
     */
    private Spliterator<?> sourceSpliterator;
       /**
    源提供者。仅对总管有效。如果非空,则在使用管道之前,sourceSpliterator必须为空。
    在使用管道之后,如果非空,则设置为空。
     */
    private Supplier<? extends Spliterator<?>> sourceSupplier;
      /**
     * True if this pipeline has been linked or consumed
     * 如果此管道已链接或使用,则为True
     */
    private boolean linkedOrConsumed;

   /**
     * 他下一个阶段正在进行,如果这是最后一个阶段,则为空
     * 有效地在连接到下一个管道时结束。
     */
    @SuppressWarnings("rawtypes")
    private AbstractPipeline nextStage;
    /**
     * “上游”管道,如果这是源阶段,则为空。
     */
    @SuppressWarnings("rawtypes")
    private final AbstractPipeline previousStage;
       /**
    在此管道对象与流源之间的中间操作个数(如果是串行的)或前一个状态(如果是并行的)。
    在管道准备计算时有效
    (此管道对象和流的源的中间操作个数)
     */
    private int depth;
      /**
   如果管道是并行的,则为True;否则管道是串行的;仅对源阶段有效。
     */
    private boolean parallel;

/*
	ReferencePipeline调用的父类的构造方法
	(构造源节点)
*/
  AbstractPipeline(Supplier<? extends Spliterator<?>> source,
                     int sourceFlags, boolean parallel) {
         //源调用时为null
        this.previousStage = null;
        //源分隔迭代器
        this.sourceSupplier = source;
        //链接头部(源所有是自己)
        this.sourceStage = this;
        this.sourceOrOpFlags = sourceFlags & StreamOpFlag.STREAM_MASK;
        // The following is an optimization of:
        // StreamOpFlag.combineOpFlags(sourceOrOpFlags, StreamOpFlag.INITIAL_OPS_VALUE);
        this.combinedFlags = (~(sourceOrOpFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE;
        //此对象和源头之间的中间操作的个数(head是源头 源头与源头之间0个中间操作)
        this.depth = 0;
        //是否是并行
        this.parallel = parallel;
    }
	/*
	用于将中间操作阶段附加到现有管道pipeline上的构造函数。
	(将中间操作阶段附加到现有管道pipeline)
	*/
	  AbstractPipeline(AbstractPipeline<?, E_IN, ?> previousStage, int opFlags) {
        if (previousStage.linkedOrConsumed)
        	// 如果流已经被使用直接抛出异常
            throw new IllegalStateException(MSG_STREAM_LINKED);
         //标识现有管道已经被使用
        previousStage.linkedOrConsumed = true;
        //标识下个中间操作头是目前的管道
        previousStage.nextStage = this;
		//将传过来的上游管道赋值
        this.previousStage = previousStage;
        this.sourceOrOpFlags = opFlags & StreamOpFlag.OP_MASK;
        this.combinedFlags = StreamOpFlag.combineOpFlags(opFlags, previousStage.combinedFlags);
        //得到连接头 连接上一个源
        this.sourceStage = previousStage.sourceStage;
        if (opIsStateful())
            sourceStage.sourceAnyStateful = true;
        //中间操作加1    
        this.depth = previousStage.depth + 1;
    }
	
 //来自流的终端操作
     // 当Stream.forEach有中间操作调用此forEach
     @Override
        public void forEach(Consumer<? super E_OUT> action) {
            if (!isParallel()) {
            /*
            传入的迭代器是返回实现类IteratorSpliterator
            所以此时调用的是该类的forEachRemaining
            具体细节看Spliterators的方法讲解
            */
                sourceStageSpliterator().forEachRemaining(action);
            }
            else {
                super.forEach(action);
            }
        }
/*
		如果此管道阶段是源阶段,则获取源阶段分隔迭代器。调用此方法将消费该管道,并成功返回。
	*/
  final Spliterator<E_OUT> sourceStageSpliterator() {
  		//当不是处于源阶段直接抛出异常
        if (this != sourceStage)
            throw new IllegalStateException();
		//如果g该管道被链接或者被消费
        if (linkedOrConsumed)
            throw new IllegalStateException(MSG_STREAM_LINKED);
            //消费了= true 表示该管道不能被使用
        linkedOrConsumed = true;
		/*
		源 通过两种方式构建sourceStage.sourceSpliterator或者
		sourceStage.sourceSupplier
	*/
        if (sourceStage.sourceSpliterator != null) {
        	//返回一个Spliterator对象
            @SuppressWarnings("unchecked")
            Spliterator<E_OUT> s = sourceStage.sourceSpliterator;
            //管道一旦被操作 必须将其设置为空
            sourceStage.sourceSpliterator = null;
            return s;
        }
        else if (sourceStage.sourceSupplier != null) {
        	//源进行操作返回一个Spliterator对象 
            @SuppressWarnings("unchecked")
            Spliterator<E_OUT> s = (Spliterator<E_OUT>) sourceStage.sourceSupplier.get();
           //管道一旦被操作 必须将其设置为空
            sourceStage.sourceSupplier = null;
            return s;
        }
        else {
            throw new IllegalStateException(MSG_CONSUMED);
        }
    }

Sink

doc

  • Consumer的一种扩展,用于在首次调用接收器上的accept()方法之前,通过流管道的各个阶段执行值,并使用其他方法管理大小信息、控制流等,必须首先调用begin()方法来通知它数据即将到来(可选地通知接收器有多少数据即将到来),并且在发送完所有数据之后,必须调用end()方法。调用end()之后,不应在不再次调用begin()的情况下调用accept())。Sink还提供了一种机制,通过这种机制,Sink可以协同地发出不希望接收更多数据的信号(cancellationRequested()方法),源可以在向Sink发送更多数据之前对其进行轮询。
  • 接收器可能处于两种状态之一:初始状态和激活状态。它从初始状态开始;begin()方法将其转换为激活状态,end()方法将其转换回初始状态,在初始状态中可以重用它。数据接受方法(如accept()仅在活动状态下有效。
    在这里插入图片描述
    用于创建汇链的抽象汇实现。begin、end和cancellationRequested方法连接到下游接收器。
    在这里插入图片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章