第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

java - 在Java Stream API中,中間操作被延遲執(zhí)行而終端操作被急切執(zhí)行是什么意思?

java - 在Java Stream API中,中間操作被延遲執(zhí)行而終端操作被急切執(zhí)行是什么意思?

UYOU 2021-12-01 16:12:42
list.stream().filter( a-> a < 20 && a > 7).forEach(a -> System.out.println(a));fiter 被懶惰地執(zhí)行。forEach 被急切地處決。這意味著什么?
查看完整描述

3 回答

?
長風(fēng)秋雁

TA貢獻1757條經(jīng)驗 獲得超7個贊

假設(shè)您進行了以下操作。


list.stream()

    .map(a -> a * a)

    .filter(a -> a > 0 && a < 100)

    .map(a -> -a)

    .forEach(a -> System.out.println(a));

中間操作是映射和過濾器,終端操作是forEach. 如果急切地執(zhí)行中間操作,.map(a -> a * a)則將立即映射整個流,并將結(jié)果傳遞給.filter(a -> a > 0 && a < 10)which 將立即過濾結(jié)果,然后將傳遞給.map(a -> -a)which 將映射過濾后的結(jié)果,然后將其傳遞給forEach然后立即打印流中的每個元素。


然而,中間操作不是急切的,而是懶惰的。這意味著序列


list.stream()

    .map(a -> a * a)

    .filter(a -> a > 0 && a < 100)

    .map(a -> -a)

實際上并沒有立即做任何事情。它只是創(chuàng)建一個新的流來記住它應(yīng)該執(zhí)行的操作,但直到實際產(chǎn)生結(jié)果時才真正執(zhí)行它們。直到forEach嘗試從流中讀取一個值,然后它才會轉(zhuǎn)到原始流,獲取一個值,使用 映射它a -> a * a,過濾它,如果它通過過濾器,映射它使用a -> -a,然后將該值傳遞給forEach。


這就像在餐廳工作的人被賦予了從臟堆中取出所有盤子,清洗它們,將它們堆疊起來,然后在廚師準備上菜時將它們交給廚師的工作。人急了,就立刻把整堆臟盤子拿起來,一下子洗干凈,疊好,等廚子要盤子時,一一遞給上菜。


然而,懶惰的員工會意識到廚師一次只需要一個盤子,而且只有在食物準備好時才需要。因此,當(dāng)廚師需要一個盤子時,員工只需從一堆盤子中取出一個盤子,清洗干凈并遞給廚師,一個接一個,直到所有盤子都洗干凈,所有的食物都端上來為止。


那么有什么好處呢?


一個主要優(yōu)點是惰性方法大大改善了延遲。您可能知道,程序的單個線程一次只能做一件事。進一步擴展類比,假設(shè)有大約 800 個盤子,但廚師實際上必須等待洗衣機洗完盤子,然后再將一個遞給他。如果熱心的洗碗工堅持先把盤子洗干凈再遞過來,廚師就得等著800個盤子都洗干凈了,然后一次上菜800頓,到時候憤怒的顧客都已經(jīng)離開了。


然而,有了懶惰的洗衣機,廚師每上菜,他只需要等一個盤子。因此,如果洗盤子需要 10 秒,而上菜幾乎是即時的,那么在場景 1 中,所有餐點都會一次上菜,但只有在等待兩個多小時后才能上菜。但在場景 2 中,每頓飯的供應(yīng)間隔約為 10 秒。因此,即使提供所有餐點所需的時間相同,場景 2 肯定更可取。


我在此將類比擴展了一點,但希望這可以幫助您更好地理解它。


查看完整回答
反對 回復(fù) 2021-12-01
?
撒科打諢

TA貢獻1934條經(jīng)驗 獲得超2個贊

延遲執(zhí)行意味著操作只會在必要時執(zhí)行。

急切執(zhí)行意味著操作將立即執(zhí)行。

那么你可能會問什么時候執(zhí)行惰性中間操作?

當(dāng)對管道應(yīng)用終端操作(Eager 操作)時。

那么我們?nèi)绾沃酪粋€操作是中間的(懶惰的)還是終端的(急切的)呢?

當(dāng)操作返回一個Stream<T>whereT可以是任何類型時,它就是一個中間操作(懶惰);如果操作返回任何其他內(nèi)容,即 void、int、boolean 等,那么它是終端(急切)操作。


查看完整回答
反對 回復(fù) 2021-12-01
?
慕沐林林

TA貢獻2016條經(jīng)驗 獲得超9個贊

在的JavaDoc的Stream說:


流是懶惰的;對源數(shù)據(jù)的計算僅在終端操作啟動時進行,源元素僅在需要時消費。


關(guān)于中間操作的JavaDoc:


他們總是懶惰;執(zhí)行中間操作,例如 filter()實際上并不執(zhí)行任何過濾,而是創(chuàng)建一個新的流,當(dāng)遍歷時,該流包含與給定謂詞匹配的初始流的元素。管道源的遍歷直到管道的終端操作被執(zhí)行后才開始。


由于map是一個惰性操作,以下代碼將不打印任何內(nèi)容:


Stream.of(1, 2, 3).map(i -> {

    System.out.println(i);

    return i;

});

這Stream缺少將執(zhí)行它的終端操作,這將調(diào)用中間操作。


類似list.stream().filter( a-> a > 20 && a < 7)將返回一個Stream但list尚未過濾的元素。


但即使執(zhí)行了終端操作,還有更多關(guān)于懶惰的問題:


懶惰還可以避免在不必要時檢查所有數(shù)據(jù);對于諸如“查找第一個長度超過 1000 個字符的字符串”之類的操作


如果需要執(zhí)行惰性操作來確定 a 的結(jié)果,則會執(zhí)行惰性操作Stream。并非來自源的所有元素都必須由惰性操作處理。


關(guān)于終端操作的 JavaDoc:


在幾乎所有情況下,終端操作都是急切的,在返回之前完成對數(shù)據(jù)源的遍歷和管道的處理。


此外,一個Stream.


執(zhí)行完終端操作后,流管道被認為已被消耗,不能再使用;


繼續(xù)這個例子:


long count = Stream.of(1, 2, 3).map(i -> {

    System.out.println(i);

    return i;

}).count();

確定count映射是無關(guān)緊要的。因此,此代碼仍然不會打印任何內(nèi)容。但由于count()是一個終端操作,流被處理并count獲得3分配的值。


如果我們將終端操作更改為,.min(Comparator.naturalOrder());則執(zhí)行所有映射,我們將看到打印的整數(shù)。


查看完整回答
反對 回復(fù) 2021-12-01
  • 3 回答
  • 0 關(guān)注
  • 319 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號