一開始我並不理解,為什麼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);
}
};
}
};
}