目錄
1、map / flatMap / mapToObj / mapToLong / mapToDouble /asLongStream / asDoubleStream
6、anyMatch / allMatch / noneMatch
本篇博客繼續上一篇《Java8 Stream API 之 IntPipeline(一) 源碼解析》講解IntStream其他方法的實現細節。
1、map / flatMap / mapToObj / mapToLong / mapToDouble /asLongStream / asDoubleStream
這幾個都是map類方法,都是將流中的元素做適當處理,返回一個新值或者新的流,實現基本一致,如下:
@Override
public final IntStream map(IntUnaryOperator mapper) {
Objects.requireNonNull(mapper);
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
@Override
public void accept(int t) {
//將applyAsInt的執行結果傳遞給下一個流處理動作
downstream.accept(mapper.applyAsInt(t));
}
};
}
};
}
@Override
public final IntStream flatMap(IntFunction<? extends IntStream> mapper) {
return new StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(int t) {
//flatMap的入參mapper的返回值是一個IntStream
try (IntStream result = mapper.apply(t)) {
if (result != null)
//如果mapper返回的IntStream流非空,則遍歷其中的所有元素,傳遞給下一個流處理動作
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
@Override
public final <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedInt<U>(sink) {
@Override
public void accept(int t) {
//apply方法將t轉換成對象
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final LongStream mapToLong(IntToLongFunction mapper) {
Objects.requireNonNull(mapper);
return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedInt<Long>(sink) {
@Override
public void accept(int t) {
//apply方法將t轉換成Long
downstream.accept(mapper.applyAsLong(t));
}
};
}
};
}
@Override
public final DoubleStream mapToDouble(IntToDoubleFunction mapper) {
Objects.requireNonNull(mapper);
return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedInt<Double>(sink) {
@Override
public void accept(int t) {
//apply方法將t轉換成Double
downstream.accept(mapper.applyAsDouble(t));
}
};
}
};
}
@Override
public final LongStream asLongStream() {
return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedInt<Long>(sink) {
@Override
public void accept(int t) {
downstream.accept((long) t);
}
};
}
};
}
@Override
public final DoubleStream asDoubleStream() {
return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedInt<Double>(sink) {
@Override
public void accept(int t) {
downstream.accept((double) t);
}
};
}
};
}
2、limit / skip
limit用於限制流中元素的最大個數,skip用於跳過指定個數的元素,其實現如下:
@Override
public final IntStream skip(long n) {
if (n < 0)
throw new IllegalArgumentException(Long.toString(n));
if (n == 0) //不需要跳過
return this;
else
//第一個參數表示跳過的元素個數,第二個參數表示允許的元素最大個數,-1表示無限制
return SliceOps.makeInt(this, n, -1);
}
@Override
public final IntStream limit(long maxSize) {
if (maxSize < 0)
throw new IllegalArgumentException(Long.toString(maxSize));
return SliceOps.makeInt(this, 0, maxSize);
}
//SliceOps的實現
public static IntStream makeInt(AbstractPipeline<?, Integer, ?> upstream,
long skip, long limit) {
if (skip < 0)
throw new IllegalArgumentException("Skip must be non-negative: " + skip);
return new IntPipeline.StatefulOp<Integer>(upstream, StreamShape.INT_VALUE,
flags(limit)) {
//unorderedSkipLimitSpliterator給下面兩個方法使用的
Spliterator.OfInt unorderedSkipLimitSpliterator(
Spliterator.OfInt s, long skip, long limit, long sizeIfKnown) {
if (skip <= sizeIfKnown) {
// Use just the limit if the number of elements
// to skip is <= the known pipeline size
limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip;
skip = 0;
}
return new StreamSpliterators.UnorderedSliceSpliterator.OfInt(s, skip, limit);
}
@Override
<P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator) {
long size = helper.exactOutputSizeIfKnown(spliterator);
if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
return new StreamSpliterators.SliceSpliterator.OfInt(
(Spliterator.OfInt) helper.wrapSpliterator(spliterator),
skip,
calcSliceFence(skip, limit));
} else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
return unorderedSkipLimitSpliterator(
(Spliterator.OfInt) helper.wrapSpliterator(spliterator),
skip, limit, size);
}
else {
return new SliceTask<>(this, helper, spliterator, Integer[]::new, skip, limit).
invoke().spliterator();
}
}
@Override
<P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
IntFunction<Integer[]> generator) {
long size = helper.exactOutputSizeIfKnown(spliterator);
if (size > 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
// Because the pipeline is SIZED the slice spliterator
// can be created from the source, this requires matching
// to shape of the source, and is potentially more efficient
// than creating the slice spliterator from the pipeline
// wrapping spliterator
Spliterator<P_IN> s = sliceSpliterator(helper.getSourceShape(), spliterator, skip, limit);
return Nodes.collectInt(helper, s, true);
} else if (!StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
Spliterator.OfInt s = unorderedSkipLimitSpliterator(
(Spliterator.OfInt) helper.wrapSpliterator(spliterator),
skip, limit, size);
// Collect using this pipeline, which is empty and therefore
// can be used with the pipeline wrapping spliterator
// Note that we cannot create a slice spliterator from
// the source spliterator if the pipeline is not SIZED
return Nodes.collectInt(this, s, true);
}
else {
return new SliceTask<>(this, helper, spliterator, generator, skip, limit).
invoke();
}
}
@Override
//實現skip和limit的核心方法
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
return new Sink.ChainedInt<Integer>(sink) {
long n = skip;
long m = limit >= 0 ? limit : Long.MAX_VALUE;
@Override
public void begin(long size) {
//計算遍歷的元素個數
downstream.begin(calcSize(size, skip, m));
}
@Override
public void accept(int t) {
if (n == 0) {
//n等於0表示已經跳過指定個數的元素了
if (m > 0) {
m--;
downstream.accept(t);
}
//m小於等於0表示已經達到最大元素個數限制了
}
else {
n--;
}
}
@Override
public boolean cancellationRequested() {
//m等於0了需要終止遍歷
return m == 0 || downstream.cancellationRequested();
}
};
}
};
}
abstract static class StatefulOp<E_IN> extends IntPipeline<E_IN> {
StatefulOp(AbstractPipeline<?, E_IN, ?> upstream,
StreamShape inputShape,
int opFlags) {
super(upstream, opFlags);
//校驗兩者流元素的類型是否一致
assert upstream.getOutputShape() == inputShape;
}
@Override
final boolean opIsStateful() {
return true; //StatelessOp此方法返回false
}
@Override
//此方法是父類AbstractPipeline定義的方法,默認實現是拋出UnsupportedOperationException異常
//StatefulOp的子類必須重寫此方法
abstract <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
IntFunction<Integer[]> generator);
}
private static long calcSize(long size, long skip, long limit) {
return size >= 0 ? Math.max(-1, Math.min(size - skip, limit)) : -1;
}
其中opEvaluateParallelLazy和opEvaluateParallel都是AbstractPipeline定義的方法,其默認實現如下:
<P_IN> Node<E_OUT> opEvaluateParallel(PipelineHelper<E_OUT> helper,
Spliterator<P_IN> spliterator,
IntFunction<E_OUT[]> generator) {
throw new UnsupportedOperationException("Parallel evaluation is not supported");
}
@SuppressWarnings("unchecked")
<P_IN> Spliterator<E_OUT> opEvaluateParallelLazy(PipelineHelper<E_OUT> helper,
Spliterator<P_IN> spliterator) {
return opEvaluateParallel(helper, spliterator, i -> (E_OUT[]) new Object[i]).spliterator();
}
這兩方法都是返回在並行環境下使用的線程安全的經過包裝的Spliterator和Node實現,其調用鏈如下:
因爲涉及的類和併發處理比較複雜,此處就深究了。
3、sorted
sorted用於對流中的元素排序,其實現如下:
@Override
public final IntStream sorted() {
return SortedOps.makeInt(this);
}
static <T> IntStream makeInt(AbstractPipeline<?, Integer, ?> upstream) {
return new OfInt(upstream);
}
private static final class OfInt extends IntPipeline.StatefulOp<Integer> {
OfInt(AbstractPipeline<?, Integer, ?> upstream) {
super(upstream, StreamShape.INT_VALUE,
StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
}
@Override
//flags是前一個流處理動作的combinedFlags,sink表示前一個流處理動作
public Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
Objects.requireNonNull(sink);
//如果已經排序了,則直接返回
if (StreamOpFlag.SORTED.isKnown(flags))
return sink;
else if (StreamOpFlag.SIZED.isKnown(flags))
//如果限定了元素個數
return new SizedIntSortingSink(sink);
else
//如果元素個數未知
return new IntSortingSink(sink);
}
@Override
public <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
IntFunction<Integer[]> generator) {
if (StreamOpFlag.SORTED.isKnown(helper.getStreamAndOpFlags())) {
//如果已排序好
return helper.evaluate(spliterator, false, generator);
}
else {
Node.OfInt n = (Node.OfInt) helper.evaluate(spliterator, true, generator);
int[] content = n.asPrimitiveArray();
//執行並行排序
Arrays.parallelSort(content);
//返回排序好的結果
return Nodes.node(content);
}
}
}
private static abstract class AbstractIntSortingSink extends Sink.ChainedInt<Integer> {
protected boolean cancellationWasRequested;
AbstractIntSortingSink(Sink<? super Integer> downstream) {
super(downstream);
}
@Override
public final boolean cancellationRequested() {
//父類實現是調用downstream的cancellationWasRequested方法,此處沒有調用
cancellationWasRequested = true;
return false;
}
}
private static final class SizedIntSortingSink extends AbstractIntSortingSink {
private int[] array;
private int offset;
SizedIntSortingSink(Sink<? super Integer> downstream) {
super(downstream);
}
@Override
public void begin(long size) {
//size爲流中元素的個數
if (size >= Nodes.MAX_ARRAY_SIZE)
throw new IllegalArgumentException(Nodes.BAD_SIZE);
array = new int[(int) size];
}
@Override
public void end() {
//當所有流元素都通過accept方法傳遞完成會調用end方法
//對流中元素做排序處理
Arrays.sort(array, 0, offset);
//通知下一個流處理動作開始處理
downstream.begin(offset);
if (!cancellationWasRequested) {
//如果沒有請求終止當前流處理
for (int i = 0; i < offset; i++)
//將數組中的流處理動作傳遞給下一個流
downstream.accept(array[i]);
}
else {
//如果下一個流處理動作也終止了則停止處理流元素
for (int i = 0; i < offset && !downstream.cancellationRequested(); i++)
downstream.accept(array[i]);
}
//通知下一個流處理動作處理結束
downstream.end();
array = null;
}
@Override
public void accept(int t) {
//上一個流處理動作通過此方法將硫元素傳遞給當前Sink,注意此時並不會繼續向下傳遞,而是放在array中保存起來了
array[offset++] = t;
}
}
private static final class IntSortingSink extends AbstractIntSortingSink {
//SpinedBuffer的實現跟ArrayList類似,相當於一個會自動擴容的數組
private SpinedBuffer.OfInt b;
IntSortingSink(Sink<? super Integer> sink) {
super(sink);
}
@Override
public void begin(long size) {
if (size >= Nodes.MAX_ARRAY_SIZE)
throw new IllegalArgumentException(Nodes.BAD_SIZE);
//初始化b
b = (size > 0) ? new SpinedBuffer.OfInt((int) size) : new SpinedBuffer.OfInt();
}
@Override
public void end() {
int[] ints = b.asPrimitiveArray();
//執行排序
Arrays.sort(ints);
//通知流處理開始
downstream.begin(ints.length);
//同上,將數組中排序好的流處理元素傳遞給下一個流
if (!cancellationWasRequested) {
for (int anInt : ints)
downstream.accept(anInt);
}
else {
for (int anInt : ints) {
if (downstream.cancellationRequested()) break;
downstream.accept(anInt);
}
}
//通知流處理結束
downstream.end();
}
@Override
public void accept(int t) {
//保存上一個流處理動作傳遞過來的元素
b.accept(t);
}
}
4、distinct / boxed
@Override
public final IntStream distinct() {
//很低效的實現,實際是藉助了對象流的distinct實現
return boxed().distinct().mapToInt(i -> i);
}
@Override
public final Stream<Integer> boxed() {
//轉換成對象流
return mapToObj(Integer::valueOf);
}
//ReferencePipeline就是對象流的Stream接口實現
@Override
public final Stream<P_OUT> distinct() {
return DistinctOps.makeRef(this);
}
//DistinctOps的實現
static <T> ReferencePipeline<T, T> makeRef(AbstractPipeline<?, T, ?> upstream) {
return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE,
StreamOpFlag.IS_DISTINCT | StreamOpFlag.NOT_SIZED) {
<P_IN> Node<T> reduce(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
// If the stream is SORTED then it should also be ORDERED so the following will also
// preserve the sort order
TerminalOp<T, LinkedHashSet<T>> reduceOp
= ReduceOps.<T, LinkedHashSet<T>>makeRef(LinkedHashSet::new, LinkedHashSet::add,
LinkedHashSet::addAll);
return Nodes.node(reduceOp.evaluateParallel(helper, spliterator));
}
@Override
<P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator,
IntFunction<T[]> generator) {
if (StreamOpFlag.DISTINCT.isKnown(helper.getStreamAndOpFlags())) {
// No-op
return helper.evaluate(spliterator, false, generator);
}
else if (StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
return reduce(helper, spliterator);
}
else {
// Holder of null state since ConcurrentHashMap does not support null values
AtomicBoolean seenNull = new AtomicBoolean(false);
ConcurrentHashMap<T, Boolean> map = new ConcurrentHashMap<>();
TerminalOp<T, Void> forEachOp = ForEachOps.makeRef(t -> {
if (t == null)
seenNull.set(true);
else
map.putIfAbsent(t, Boolean.TRUE);
}, false);
forEachOp.evaluateParallel(helper, spliterator);
// If null has been seen then copy the key set into a HashSet that supports null values
// and add null
Set<T> keys = map.keySet();
if (seenNull.get()) {
// TODO Implement a more efficient set-union view, rather than copying
keys = new HashSet<>(keys);
keys.add(null);
}
return Nodes.node(keys);
}
}
@Override
<P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {
if (StreamOpFlag.DISTINCT.isKnown(helper.getStreamAndOpFlags())) {
// No-op
return helper.wrapSpliterator(spliterator);
}
else if (StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {
// Not lazy, barrier required to preserve order
return reduce(helper, spliterator).spliterator();
}
else {
// Lazy
return new StreamSpliterators.DistinctSpliterator<>(helper.wrapSpliterator(spliterator));
}
}
@Override
Sink<T> opWrapSink(int flags, Sink<T> sink) {
Objects.requireNonNull(sink);
if (StreamOpFlag.DISTINCT.isKnown(flags)) {
//之前的流處理動作已經去重過了,則直接返回
return sink;
} else if (StreamOpFlag.SORTED.isKnown(flags)) {
//如果是一個已經排序好的流
return new Sink.ChainedReference<T, T>(sink) {
boolean seenNull;
T lastSeen;
@Override
public void begin(long size) {
seenNull = false;
lastSeen = null;
downstream.begin(-1);
}
@Override
public void end() {
seenNull = false;
lastSeen = null;
downstream.end();
}
@Override
public void accept(T t) {
if (t == null) {
if (!seenNull) { //如果沒有遇到過null
seenNull = true;
downstream.accept(lastSeen = null);
}
//已經遇到過null了則不做處理
} else if (lastSeen == null || !t.equals(lastSeen)) {
//如果t是第一個處理的元素或者t跟上一個元素不一樣,則將其傳遞給下一個流
//因爲是排序好的,所以只可能跟上一個元素重複
downstream.accept(lastSeen = t);
}
}
};
} else {
//如果是一個未排序的流
return new Sink.ChainedReference<T, T>(sink) {
Set<T> seen;
@Override
public void begin(long size) {
//初始化HashSet
seen = new HashSet<>();
downstream.begin(-1);
}
@Override
public void end() {
seen = null;
downstream.end();
}
@Override
public void accept(T t) {
if (!seen.contains(t)) {
//不包含這個元素,則傳遞給下一個元素
seen.add(t);
downstream.accept(t);
}
}
};
}
}
};
}
5、findFirst / findAny
findFirst是查找並返回第一個元素,findAny是返回任意一個元素,其實現如下:
@Override
public final OptionalInt findFirst() {
return evaluate(FindOps.makeInt(true));
}
@Override
public final OptionalInt findAny() {
return evaluate(FindOps.makeInt(false));
}
public static TerminalOp<Integer, OptionalInt> makeInt(boolean mustFindFirst) {
return new FindOp<>(mustFindFirst, StreamShape.INT_VALUE, OptionalInt.empty(),
//最後一個參數sinkSupplier是一個可以通過get方法返回FindSink.OfInt的Supplier
OptionalInt::isPresent, FindSink.OfInt::new);
}
private static final class FindOp<T, O> implements TerminalOp<T, O> {
private final StreamShape shape;
final boolean mustFindFirst;
final O emptyValue;
final Predicate<O> presentPredicate;
final Supplier<TerminalSink<T, O>> sinkSupplier;
FindOp(boolean mustFindFirst,
StreamShape shape,
O emptyValue,
Predicate<O> presentPredicate,
Supplier<TerminalSink<T, O>> sinkSupplier) {
this.mustFindFirst = mustFindFirst;
this.shape = shape;
this.emptyValue = emptyValue;
this.presentPredicate = presentPredicate;
this.sinkSupplier = sinkSupplier;
}
@Override
public int getOpFlags() {
//增加IS_SHORT_CIRCUIT標識符,則遍歷的過程中如果cancellationRequested方法會true了則會終止遍歷
return StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
}
@Override
public StreamShape inputShape() {
return shape;
}
@Override
//串行執行時 evaluate方法調用此方法
public <S> O evaluateSequential(PipelineHelper<T> helper,
Spliterator<S> spliterator) {
//wrapAndCopyInto返回一個TerminalSink實現,get方法是其父類Supplier接口的方法
O result = helper.wrapAndCopyInto(sinkSupplier.get(), spliterator).get();
return result != null ? result : emptyValue;
}
@Override
//並行執行時 evaluate方法調用此方法
public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator) {
return new FindTask<>(this, helper, spliterator).invoke();
}
}
private static abstract class FindSink<T, O> implements TerminalSink<T, O> {
boolean hasValue;
T value;
FindSink() {} // Avoid creation of special accessor
@Override
public void accept(T value) {
if (!hasValue) {
//如果已經接收了一個元素,則將hasValue置爲true
//注意此時沒有向下傳遞流元素,因爲find操作是流終止類操作
hasValue = true;
this.value = value;
}
}
@Override
public boolean cancellationRequested() {
//父類默認返回false,如果已經接收了一個元素則返回true
return hasValue;
}
/** Specialization of {@code FindSink} for int streams */
static final class OfInt extends FindSink<Integer, OptionalInt>
implements Sink.OfInt {
@Override
public void accept(int value) {
//調用父類方法
accept((Integer) value);
}
@Override
public OptionalInt get() {
//如果有值則構造一個OptionalInt,否則返回null
return hasValue ? OptionalInt.of(value) : null;
}
}
}
從其實現可知,兩者在串行條件下返回的結果是一樣的,且找到一個元素後會終止流元素處理,測試用例如下:
@Test
public void test3() throws Exception {
IntStream stream=IntStream.range(1,10);
int a=stream.peek(x->{
System.out.println(x);
// }).findFirst().getAsInt();
}).findAny().getAsInt();
System.out.println(a);
}
findFirst和findAny的輸出是一樣的,如下:
6、anyMatch / allMatch / noneMatch
anyMatch表示任意一個匹配返回true,allMatch所有的都匹配返回true,noneMatch沒有一個匹配返回true,其實現如下:
@Override
public final boolean anyMatch(IntPredicate predicate) {
return evaluate(MatchOps.makeInt(predicate, MatchOps.MatchKind.ANY));
}
@Override
public final boolean allMatch(IntPredicate predicate) {
return evaluate(MatchOps.makeInt(predicate, MatchOps.MatchKind.ALL));
}
@Override
public final boolean noneMatch(IntPredicate predicate) {
return evaluate(MatchOps.makeInt(predicate, MatchOps.MatchKind.NONE));
}
//MatchOps的實現
public static TerminalOp<Integer, Boolean> makeInt(IntPredicate predicate,
MatchKind matchKind) {
Objects.requireNonNull(predicate);
Objects.requireNonNull(matchKind);
class MatchSink extends BooleanTerminalSink<Integer> implements Sink.OfInt {
MatchSink() {
super(matchKind);
}
@Override
public void accept(int t) {
//stop默認是false
//ANY時stopOnPredicateMatches爲true,ALL時stopOnPredicateMatches爲false
//NONE時stopOnPredicateMatches爲true,參考後面的MatchKind定義
if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
stop = true; //變成true,終止遍歷
//設置處理結果
value = matchKind.shortCircuitResult;
}
}
}
return new MatchOp<>(StreamShape.INT_VALUE, matchKind, MatchSink::new);
}
private static abstract class BooleanTerminalSink<T> implements Sink<T> {
boolean stop; //是否停止遍歷
boolean value; //返回的結果
BooleanTerminalSink(MatchKind matchKind) {
value = !matchKind.shortCircuitResult;
}
public boolean getAndClearState() {
return value;
}
@Override
public boolean cancellationRequested() {
return stop;
}
}
private static final class MatchOp<T> implements TerminalOp<T, Boolean> {
private final StreamShape inputShape;
final MatchKind matchKind;
final Supplier<BooleanTerminalSink<T>> sinkSupplier;
MatchOp(StreamShape shape,
MatchKind matchKind,
Supplier<BooleanTerminalSink<T>> sinkSupplier) {
this.inputShape = shape;
this.matchKind = matchKind;
this.sinkSupplier = sinkSupplier;
}
@Override
public int getOpFlags() {
//加上IS_SHORT_CIRCUIT標識,如果Sink的cancellationRequested返回true則終止流元素遍歷
return StreamOpFlag.IS_SHORT_CIRCUIT | StreamOpFlag.NOT_ORDERED;
}
@Override
public StreamShape inputShape() {
return inputShape;
}
@Override
public <S> Boolean evaluateSequential(PipelineHelper<T> helper,
Spliterator<S> spliterator) {
//串行處理時調用
return helper.wrapAndCopyInto(sinkSupplier.get(), spliterator).getAndClearState();
}
@Override
public <S> Boolean evaluateParallel(PipelineHelper<T> helper,
Spliterator<S> spliterator) {
//並行處理時調用
return new MatchTask<>(this, helper, spliterator).invoke();
}
}
enum MatchKind {
/** Do all elements match the predicate? */
ANY(true, true),
/** Do any elements match the predicate? */
ALL(false, false),
/** Do no elements match the predicate? */
NONE(true, false);
private final boolean stopOnPredicateMatches;
private final boolean shortCircuitResult;
private MatchKind(boolean stopOnPredicateMatches,
boolean shortCircuitResult) {
this.stopOnPredicateMatches = stopOnPredicateMatches;
this.shortCircuitResult = shortCircuitResult;
}
}
7、iterator / spliterator
iterator返回流中元素的遍歷器,spliterator返回當前流處理關聯的Spliterator實現,其實現如下:
@Override
public final PrimitiveIterator.OfInt iterator() {
return Spliterators.iterator(spliterator());
}
@Override
public final Spliterator.OfInt spliterator() {
return adapt(super.spliterator());
}
public static PrimitiveIterator.OfInt iterator(Spliterator.OfInt spliterator) {
Objects.requireNonNull(spliterator);
class Adapter implements PrimitiveIterator.OfInt, IntConsumer {
boolean valueReady = false;
int nextElement;
@Override
public void accept(int t) {
//接收一個新的流元素
valueReady = true; //表示nextElement是否存在,如果被取走則被置爲false
nextElement = t;
}
@Override
public boolean hasNext() {
if (!valueReady)
//tryAdvance會遍歷流中的元素,遍歷一個後調用上面的accept方法
spliterator.tryAdvance(this);
return valueReady;
}
@Override
public int nextInt() {
if (!valueReady && !hasNext()) //如果nextElement沒有且hasNext返回false,說明沒有多餘的元素了
throw new NoSuchElementException();
else {
valueReady = false;
return nextElement;
}
}
}
return new Adapter();
}
private static Spliterator.OfInt adapt(Spliterator<Integer> s) {
if (s instanceof Spliterator.OfInt) {
return (Spliterator.OfInt) s;
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(AbstractPipeline.class,
"using IntStream.adapt(Spliterator<Integer> s)");
throw new UnsupportedOperationException("IntStream.adapt(Spliterator<Integer> s)");
}
}
8、close / onClose
onClose表示註冊關閉流即執行close時的回調動作,close表示關閉流,注意跟流終止動作關閉流是兩碼事。
@Override
public void close() {
linkedOrConsumed = true;
sourceSupplier = null;
sourceSpliterator = null;
if (sourceStage.sourceCloseAction != null) {
//如果回調動作不爲空的話,則執行回調
Runnable closeAction = sourceStage.sourceCloseAction;
sourceStage.sourceCloseAction = null;
closeAction.run();
}
}
@Override
@SuppressWarnings("unchecked")
public S onClose(Runnable closeHandler) {
Objects.requireNonNull(closeHandler);
Runnable existingHandler = sourceStage.sourceCloseAction;
sourceStage.sourceCloseAction =
(existingHandler == null) //如果沒有註冊關閉時的回調動作則直接賦值,否則調用composeWithExceptions註冊多個
? closeHandler
: Streams.composeWithExceptions(existingHandler, closeHandler);
return (S) this;
}
static Runnable composeWithExceptions(Runnable a, Runnable b) {
//返回一個新的Runnable,同時包裹了a和b,a表示已經存在的回調動作,b表示新增的回調動作
//會保證a先執行,且無論a是否異常,b都會被執行
return new Runnable() {
@Override
public void run() {
try {
a.run();
}
catch (Throwable e1) {
try {
b.run();
}
catch (Throwable e2) {
try {
e1.addSuppressed(e2);
} catch (Throwable ignore) {}
}
throw e1;
}
b.run();
}
};
}