亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

無法理解 lambda 和 longstream 方法

無法理解 lambda 和 longstream 方法

慕桂英4014372 2022-12-15 10:53:10
我有這樣的代碼示例。import java.util.LinkedList;import java.util.List;import java.util.stream.LongStream;public class RemovedNumbers {    public static List<long[]> removNb(long n) {        System.out.println(n);        long sum = ((n + 1) * n / 2);        long minMultiplication = sum - 2 * n + 1;        long minCandidate = (long) Math.sqrt(minMultiplication);        LinkedList<long[]> list = new LinkedList<>();        LongStream.rangeClosed(minCandidate, n)                  .mapToObj(a -> new long[]{a, calculateB(a, sum)})                  .filter(longs -> longs[0] > longs[1])                  .filter(longs -> longs[1] <= n)                  .filter(longs -> longs[0] * longs[1] == sum - longs[0] - longs[1])                  .forEach(longs -> addArrays(list, longs));        return list;    }    private static long calculateB(long a, long sum) {        return (sum - a) / (a + 1);    }    private static void addArrays(final LinkedList<long[]> list, final long[] longs) {        list.addFirst(new long[]{longs[1], longs[0]});        list.add(longs);    }}這段代碼在 LongStream 部分對我來說很復雜。 我沒有得到一些分數,所以我需要幫助:我檢查了 LongStream 類。此類使用四種方法:rangeClosed、mapToObj、filter、forEach(我在 Java 文檔中找到了它們的描述)。不幸的是,現在我開始檢查 java 1.8 版本,所以我無法理解它是如何工作的以及發生了什么。"a"mapToObj出現在哪里?它是什么?"a"我在前面的代碼部分沒有看到 var聲明。因為我有 lambda 是由這樣的方案制作的:(arguments) -> (body). 所以 the"a"是一個論點,"new long[]..."- 是一個主體。這部分對我來說沒有任何問題。但是下一個 whereis "longs"- 論點,“longs[0] > longs[1]” - body,引起了一些問題。什么是變量"longs"?以前沒有申報過!它是如何出現的?這個怎么運作?LongStream 類可以寫在一行中,我說得對嗎?喜歡:LongStream.rangeClosed().filter().filter().filter().forEach(); ?所有方法都因此執行,我說得對嗎?靠彼此?第一個rangeClosed,然后是mapToObj,然后是filter……還是有別的順序?非常感謝!
查看完整描述

4 回答

?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

您的第三點回答了您的第二點 -a是傳遞給 的 lambda 表達式的參數mapToObj

如果你能理解這一點,那么你的第四點應該也很容易理解。longs是傳遞給 的 lambda 表達式的參數filter。請記住,您可以隨意命名參數名稱。我猜想代碼作者之所以將參數重命名為longs是因為在上一行long中,流中的每個都被映射到一個long[],所以現在它是一個長數組流。

LongStream 類可以寫在一行中,我說得對嗎?

是的,但你最終會得到一長串代碼,所以我們幾乎從不這樣做。

所有方法都因此執行,我說得對嗎?靠對方?第一個rangeClosed,然后是mapToObj,然后是filter……還是有別的順序?

這些方法按該順序被調用,但它們執行的操作不會立即運行。這是流很酷的部分。當您這樣做時,多頭只會被mapToObj'ed 和'ed,這是一個終端操作。換句話說,和有點像在說“這就是這個流應該做的......”當你這樣做的時候,你是在說“現在就去做吧!”filterforEachmapToObjfilterforEach

如果您仍然不明白流在做什么,請嘗試將它們想象成工廠中的一條生產線。一開始,你longs在傳送帶上。然后他們通過一臺機器,把他們每個人都變成一個long[]. 之后,它們通過三個過濾器。除非長陣列滿足某些條件,否則這些過濾器會將它們推離傳送帶。

編輯:

如果您想在不使用 lambda 的情況下編寫此代碼,則可以使用匿名類來編寫它:

LongStream.rangeClosed(minCandidate, n)

        .mapToObj(new LongFunction<long[]>() {

            @Override

            public long[] apply(long a) {

                return new long[]{a, calculateB(a, sum)};

            }

        })

        .filter(new Predicate<long[]>() {

            @Override

            public boolean test(long[] longs) {

                return longs[0] > longs[1] && 

                        longs[1] <= n && 

                        longs[0] * longs[1] == sum - longs[0] - longs[1];

            }

        })

        .forEach(new Consumer<long[]>() {

            @Override

            public void accept(long[] longs) {

                addArrays(list, longs);

            }

        });


查看完整回答
反對 回復 2022-12-15
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

LongStream 類可以寫在一行中,我說得對嗎?

您在這里看到的是方法鏈接。這是一個接一個的方法可以相互鏈接的地方。幾乎所有類都可以這樣做。

Sweeper 幾乎回答了其他所有問題。


查看完整回答
反對 回復 2022-12-15
?
函數式編程

TA貢獻1807條經驗 獲得超9個贊

每個 lambda 表達式都實現了一個函數式接口,或者更具體地說,它實現了該函數式接口的單個抽象方法。

因此,在 中a -> new long[]{a, calculateB(a, sum)},a是函數式接口實現的方法的參數。由于mapToObj接受類型為 的參數LongFunction,因此此 lambda 表達式實現了R apply(long value)該接口的方法,這意味著 lambda 表達式也可以寫為(long a) -> new long[]{a, calculateB(a, sum)}.

mapToObj調用將 the 轉換LongStream為 a Stream<long[]>,因此以下filter調用的 lambda 表達式 -longs -> longs[0] > longs[1]也可以寫成(long[] longs) -> longs[0] > longs[1]- 它實現了功能接口Predicate<long[]>,這意味著它實現了boolean test(long[] t)。

是的,您可以在一行中編寫整個流管道,但拆分成多行會更具可讀性。

所有方法都因此執行,我說得對嗎?靠對方?第一個rangeClosed,然后是mapToObj,然后是filter...還是有別的順序

不完全是。雖然每個中間方法都會產生一個輸出用作下一個方法的輸入,但這些方法的評估僅在終端操作(forEach在本例中)執行后才開始。而且這些操作不一定處理Stream. 例如,如果終端操作firstFirst()不是forEach,則管道將只處理足夠的元素,直到找到第一個通過所有過濾器的元素。


查看完整回答
反對 回復 2022-12-15
?
SMILET

TA貢獻1796條經驗 獲得超4個贊

3 和 4:


您正在嘗試了解 lambda 的工作原理,所以我會為您分解代碼:


// this return a LongStream obj 

LongStream.rangeClosed(minCandidate, n)

// so with point notation you can access to one of the method in LongStream

// matToObj in this case.

.mapToObj(a -> new long[]{a, calculateB(a, sum)}) 

什么是 什么->?什么其他的東西?


MapToObj 采用 IntFunction 映射器參數,a是該類型的動態聲明,這就是您之前在代碼中沒有看到它的原因。箭頭表示正確的位置是 lamba 表達式,如果你有一個內聯操作,你可以省略 return 語句并且你不能包含 {} 括號所以想象這個語句就像一個 return 語句。使用 lamba 函數,您可以輕松創建操作鏈,這就是為什么您需要一個接一個地調用許多函數。您必須記住,下一個函數將一個對象類型作為參數,該對象類型與前一個函數的返回類型相同。


查看完整回答
反對 回復 2022-12-15
  • 4 回答
  • 0 關注
  • 124 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號