4 回答

TA貢獻1834條經驗 獲得超8個贊
您的第三點回答了您的第二點 -a
是傳遞給 的 lambda 表達式的參數mapToObj
。
如果你能理解這一點,那么你的第四點應該也很容易理解。longs
是傳遞給 的 lambda 表達式的參數filter
。請記住,您可以隨意命名參數名稱。我猜想代碼作者之所以將參數重命名為longs
是因為在上一行long
中,流中的每個都被映射到一個long[]
,所以現在它是一個長數組流。
LongStream 類可以寫在一行中,我說得對嗎?
是的,但你最終會得到一長串代碼,所以我們幾乎從不這樣做。
所有方法都因此執行,我說得對嗎?靠對方?第一個rangeClosed,然后是mapToObj,然后是filter……還是有別的順序?
這些方法按該順序被調用,但它們執行的操作不會立即運行。這是流很酷的部分。當您這樣做時,多頭只會被mapToObj
'ed 和'ed,這是一個終端操作。換句話說,和有點像在說“這就是這個流應該做的......”當你這樣做的時候,你是在說“現在就去做吧!”filter
forEach
mapToObj
filter
forEach
如果您仍然不明白流在做什么,請嘗試將它們想象成工廠中的一條生產線。一開始,你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);
}
});

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
,則管道將只處理足夠的元素,直到找到第一個通過所有過濾器的元素。

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 函數,您可以輕松創建操作鏈,這就是為什么您需要一個接一個地調用許多函數。您必須記住,下一個函數將一個對象類型作為參數,該對象類型與前一個函數的返回類型相同。
添加回答
舉報