java stream api reduce與collect的用法差異

java stream api reduce與collect的用法差異

java stream api中 reduce與collect 在功能上有差異也有重疊,但是重疊部分的實現也存在差異。

比入我們要爲一個數值列表求和,求和的結果將從int升級成long,因爲多個int值相加有可能會變成long。 用reduce可通過如下代碼實現

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個參數,第一個是基礎值。第二個參數是一個表達式,作用是將結果累加,並將每一個的累加結果返回。第三個參數可以無視,它只在parallelStream中有效。

再來看看collect的實現方法

        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個參數,第一個參數也是基礎值,不過這個基礎值並非和reduce方法中的第一個參數一樣直接接受一個基礎值,它接受的是一個表達式,此表達式返回一個基礎值。第二個參數作用也和reduce的第二個參數相同,用於每一步的累加操作,不同的是collect中此表達式參數不用返回執行後的結果,因此它操作的對象必須是一個引用,否者操作的結果就丟失了。這也導致了collect的運算對象必須是一個引用,包括第一個參數返回的基礎值也必須是一個引用,這便是collect和reduce這這個相同的功能中的不同點。這也是上面的代碼不適用long而使用AtomicLong的原因,如果你不喜歡使用AtomicLong,那麼也可以使用long類型的數組代替,代碼如下,能達到和上面相同的效果

        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);

因爲數組是引用類型。

至於第三個參數, 和reduce的第三個參數相同,它在普通的stream不會被執行到,在parallelStream中才會被執行,所以通常我們可以隨便些一個表達式填充下通過編譯起的編譯即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章