Java中stream流的filter機制理解

小胜爱编程發表於2024-08-20

一開始我並不理解,為什麼filter接受一個實現了Predicate介面的物件後,就能透過重寫的test方法來篩選元素,這個將篩選後的元素放到新的流中,我並不知道如何實現的。
後來我發現ReferencePipeline抽象類中重寫了filter方法,並且Collection中的stream方法返回的是StreamSupport.stream方法,而StreamSupport.stream方法返回的是ReferencePipeline.Head()。所以大致機制應該是建立的stream物件本質是建立的關於ReferencePipeline的物件,所以使用stream的filter方法實際上是呼叫的ReferencePipeline重寫後的方法。在ReferencePipeline類中應該實現了返回新的ReferencePipeline物件,並且將經過中間方法後的元素放到新的物件上面。

arrayList.stream()

default Stream<E> stream() {
        return **StreamSupport.stream**(spliterator(), false);
    }

public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel) {
        Objects.requireNonNull(spliterator);
        **return new ReferencePipeline.Head**<>(spliterator,
                                            StreamOpFlag.fromCharacteristics(spliterator),
                                            parallel);
    }

public final Stream<P_OUT> **filter**(Predicate<? super P_OUT> predicate) {
        Objects.requireNonNull(predicate);
        return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SIZED) {
            @Override
            Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                    @Override
                    public void begin(long size) {
                        downstream.begin(-1);
                    }

                    @Override
                    public void accept(P_OUT u) {
                        if (predicate.test(u))
                            downstream.accept(u);
                    }
                };
            }
        };
    }

相關文章