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方法連接到下游接收器。