Java变长数组笛卡尔积_Java 8中的流作为流的笛卡尔积(仅使用流)
小編典典
在示例中傳遞流永遠比傳遞列表更好:
private static Stream cartesian(BinaryOperator aggregator, List... lists) {
...
}
并像這樣使用它:
Stream result = cartesian(
(a, b) -> a + b,
Arrays.asList("A", "B"),
Arrays.asList("K", "L"),
Arrays.asList("X", "Y")
);
在這兩種情況下,您都將根據varargs創建一個隱式數組并將其用作數據源,因此懶惰是虛構的。您的數據實際上存儲在數組中。
在大多數情況下,生成的笛卡爾積流比輸入要長得多,因此實際上沒有理由使輸入變懶。例如,有五個包含五個元素的列表(總計25個),您將得到3125個元素的結果流。因此,在內存中存儲25個元素并不是很大的問題。實際上,在大多數實際情況下,它們已經存儲在內存中。
為了生成笛卡爾乘積流,您需要不斷地“倒帶”所有流(第一個流除外)。要倒帶,這些流應該能夠一次又一次地檢索原始數據,要么以某種方式緩沖它們(您不喜歡),要么從源(Colleciton,數組,文件,網絡,隨機數等)中再次獲取它們。
),并一次又一次執行所有中間操作。如果您的源操作和中間操作很慢,那么惰性解決方案可能比緩沖解決方案要慢得多。如果您的源無法再次生成數據(例如,隨機數生成器無法生成與之前生成的數字相同的數字),則您的解決方案將是錯誤的。
然而,完全懶惰的解決方案是可能的。只使用流而不是流供應商:
private static Stream cartesian(BinaryOperator aggregator,
Supplier>... streams) {
return Arrays.stream(streams)
.reduce((s1, s2) ->
() -> s1.get().flatMap(t1 -> s2.get().map(t2 -> aggregator.apply(t1, t2))))
.orElse(Stream::empty).get();
}
當我們創建并減少供應商流以得到最終的供應商并最終對其進行調用時,該解決方案很有趣。用法:
Stream result = cartesian(
(a, b) -> a + b,
() -> Stream.of("A", "B"),
() -> Stream.of("K", "L"),
() -> Stream.of("X", "Y")
);
result.forEach(System.out::println);
2020-09-16
總結
以上是生活随笔為你收集整理的Java变长数组笛卡尔积_Java 8中的流作为流的笛卡尔积(仅使用流)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “土豪金”的正确打开方式:18K黄金定制
- 下一篇: decision(decision是什么