java8--- 手動實現Collector.toList() reduce


 

 

上述的demo中發現reduce和collect的作用幾乎一樣,都是返回一個最終的結果,比如,我們可以使用reduce實現toList效果:

//手動實現toListCollector  --- 濫用reduce, 不可變的規約---不可以並行
List<Integer> calories = dishes.stream().map(Dish::getCalories)
        .reduce(new ArrayList<Integer>(),
                (List<Integer> l, Integer e) -> {
                    l.add(e);
                    return l;
                },
                (List<Integer> l1, List<Integer> l2) -> {
                    l1.addAll(l2);
                    return l1;
                }
        );
關於上述做法解釋一下。

<U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);
U是返回值類型,這里就是List BiFunction
<U, ? super T, U> accumulator是是累加器,目標在於累加值和單個元素的計算規則。這里就是List和元素做運算,最終返回List。即,添加一個元素到list。 BinaryOperator<U> combiner是組合器,目標在於把兩個返回值類型的變量合並成一個。這里就是兩個list合並。 這個解決方案有兩個問題:一個是語義問題,一個是實際問題。語義問題在於,reduce方法旨在把兩個值結合起來生成一個新值,它是一個不可變歸約。相反,collect方法的設計就是要改變容器,從而累積要輸出的結果。這意味着,上面的代碼片段是在
濫用reduce方法,因為它在原地改變了作為累加器的List。錯誤的語義來使用reduce方法還會造成一個實際問題:這個歸約不能並行工作,因為由多個線程並發修改同一個數據結構可能會破壞List本身。在這種情況下,如果你想要線程安全,就需要每次分
配一個新的List,而對象分配又會影響性能。這就是collect適合表達可變容器上的歸約的原因,更關鍵的是它適合並行操作。 總結:reduce適合不可變容器歸約,collect適合可變容器歸約。collect適合並行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM