java stream api reduce與collect的用法差異
java stream api中 reduce與collect 在功能上有差異也有重疊妓湘,但是重疊部分的實現(xiàn)也存在差異险绘。
比入我們要為一個數(shù)值列表求和,求和的結果將從int升級成long右钾,因為多個int值相加有可能會變成long轻要。 用reduce可通過如下代碼實現(xiàn)
List<Integer> numList = Arrays.asList(1,Integer.MAX_VALUE);
long reduceResult = numList.stream().reduce(0L, (a, b) -> a + b, (a, b) -> 0L);
System.out.println(reduceResult);
reduce方法接受3個參數(shù)复旬,第一個是基礎值。第二個參數(shù)是一個表達式冲泥,作用是將結果累加驹碍,并將每一個的累加結果返回壁涎。第三個參數(shù)可以無視,它只在parallelStream中有效志秃。
再來看看collect的實現(xiàn)方法
List<Integer> numList = Arrays.asList(1,Integer.MAX_VALUE);
long collectResult = numList.stream().collect(
() -> new AtomicLong(0),
(a, b) -> a.addAndGet(b),
(a, b) -> {
})
.get();
System.out.println(collectResult);
collect也接受3個參數(shù)怔球,第一個參數(shù)也是基礎值,不過這個基礎值并非和reduce方法中的第一個參數(shù)一樣直接接受一個基礎值浮还,它接受的是一個表達式竟坛,此表達式返回一個基礎值。第二個參數(shù)作用也和reduce的第二個參數(shù)相同钧舌,用于每一步的累加操作担汤,不同的是collect中此表達式參數(shù)不用返回執(zhí)行后的結果,因此它操作的對象必須是一個引用洼冻,否者操作的結果就丟失了崭歧。這也導致了collect的運算對象必須是一個引用,包括第一個參數(shù)返回的基礎值也必須是一個引用撞牢,這便是collect和reduce這這個相同的功能中的不同點率碾。這也是上面的代碼不適用long而使用AtomicLong的原因,如果你不喜歡使用AtomicLong屋彪,那么也可以使用long類型的數(shù)組代替所宰,代碼如下,能達到和上面相同的效果
List<Integer> numList = Arrays.asList(1,Integer.MAX_VALUE);
long collectResult = numList.stream().collect(
() -> {
long[] array = new long[]{0};
return array;
},
(a, b) -> a[0] += b,
(a, b) -> {})[0];
System.out.println(collectResult);
因為數(shù)組是引用類型撼班。
至于第三個參數(shù)歧匈, 和reduce的第三個參數(shù)相同垒酬,它在普通的stream不會被執(zhí)行到砰嘁,在parallelStream中才會被執(zhí)行,所以通常我們可以隨便些一個表達式填充下通過編譯起的編譯即可勘究。