簡體   English   中英

Java Stream API 惰性求值內部

[英]Java Stream API lazy evaluation internals

我正在寫一篇關於 Java Stream API 的文章。 我已經閱讀了 Stream 的整個 package 文檔,並且在這里查看了類似的問題。

如果我說以下內容:“stream 上的中間操作在終端操作被命中之前不會被評估,這實際上會執行它們,”我是否正確? 我在 StackOverflow 上看到了不同的答案,而且每個中間操作都返回一個 Stream,所以我想知道它是否只是返回自己,然后只是跟蹤中間操作以執行它。 這就是“惰性評估/執行”的意思嗎?

下面的javadoc老實說給了我混合的信號..也許我只是愚蠢

中間操作返回一個新的 stream。 他們總是很懶惰; 執行諸如 filter() 之類的中間操作實際上並沒有執行任何過濾,而是創建了一個新的 stream,當被遍歷時,它包含與給定謂詞匹配的初始 stream 的元素。 直到管道的終端操作被執行,管道源的遍歷才開始。

非常感謝您的時間; 抱歉,如果我遺漏了什么;(我已經堅持了很長時間!

PS: Stream和惰性求值非常相似,但是“每個中間操作都會創建一個新的stream,存儲提供的操作/函數並返回新的stream。” 所以基本上,我的問題是,通過新的 stream,它是否意味着與給出的 stream 相同?

所以我想知道它是否剛剛返回

中間操作不會返回給定的 stream。 正如 JavaDoc 所說,它們返回一個新的 stream ,即一個新的 object。

如果是新的 object,它怎么知道之前在 stream 上所做的操作?

……你可能會問。

好吧,對象可以引用其他對象,對嗎? 即使您返回執行“映射”的新Stream ,它仍然可以引用“舊流”(又名upstream )。 非常簡化的例子:

class StreamThatDoesMapping<U, T> implements Stream<T> {
    private Stream<U> upstream;
    private Function<? super U, ? extends T> mappingFunction;

    public StreamThatDoesMapping(Stream<U> upstream, Function<? super U, ? extends T> mappingFunction) {
        this.upstream = upstream;
        this.mappingFunction = mappingFunction;
    }

    // implementation details...
}

顯然,在實現map時,如果您將上游( this )傳遞給StreamThatDoesMapping ,新的 stream 將“了解”您之前所做的操作! 這就是您可能實現map的方式,再次非常簡化:

public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
    return new StreamThatDoesMapping<>(this, mapper);
}

當您進行終端操作時,您是在“最下游” Stream object 上進行操作,即 object 將從其上游獲取元素,因此上游將從上游獲取元素, 有點像鏈表,不是嗎?

請注意,這只是下游了解上游的一種方式。 可能還有其他的,但這是ReferencePipeline實現使用的。 這是 JDK 中大多數stream()方法返回的內容。 我強烈建議查看他們的源代碼。

如果我說以下內容:“stream 上的中間操作在終端操作被命中之前不會被評估,這實際上會執行它們,”我是否正確?

是的。

我想知道它是否只是自行返回,然后只是跟蹤要執行的中間操作。

不。

它返回一個新的Stream object,它是根據之前的Stream ZA8CFDE633119446B8 定義的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM