Java8 Stream API 之 IntPipeline(二) 源碼解析

目錄

1、map / flatMap / mapToObj / mapToLong / mapToDouble /asLongStream / asDoubleStream

          2、limit / skip

3、sorted

4、distinct / boxed

5、findFirst / findAny

6、anyMatch / allMatch / noneMatch

7、iterator / spliterator

8、close / onClose


     本篇博客繼續上一篇《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();
            }
        };
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章