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方法連接到下游接收器。
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章