Java8函数式编程(3)--规约操作
規(guī)約操作(reduction operation)又被稱作折疊操作(fold),是通過某個連接動作將所有元素匯總成一個匯總結(jié)果的過程。元素求和、求最大值或最小值、求出元素總個數(shù)、將所有元素轉(zhuǎn)換成一個列表或集合,都屬于規(guī)約操作。Stream類庫有兩個通用的規(guī)約操作reduce()和collect(),也有一些為簡化書寫而設(shè)計的專用規(guī)約操作,比如sum()、max()、min()、count()等。
reduce
reduce操作可以實現(xiàn)從一組元素中生成一個值,sum()、max()、min()、count()等都是reduce操作,將他們單獨設(shè)為函數(shù)只是因為常用。reduce()的方法定義有三種重寫形式:
Optional<T> reduce(BinaryOperator<T> accumulator) T reduce(T identity, BinaryOperator<T> accumulator) <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)reduce()最常用的場景就是從一堆值中生成一個值。
reduce最終處理會封裝成一個AccumulatingSink。
public static <T> TerminalOp<T, Optional<T>>makeRef(BinaryOperator<T> operator) {Objects.requireNonNull(operator);class ReducingSinkimplements AccumulatingSink<T, Optional<T>, ReducingSink> {private boolean empty;private T state;public void begin(long size) {empty = true;state = null;}@Overridepublic void accept(T t) {if (empty) {empty = false;state = t;} else {state = operator.apply(state, t);}}@Overridepublic Optional<T> get() {return empty ? Optional.empty() : Optional.of(state);}@Overridepublic void combine(ReducingSink other) {if (!other.empty)accept(other.state);}}return new ReduceOp<T, Optional<T>, ReducingSink>(StreamShape.REFERENCE) {@Overridepublic ReducingSink makeSink() {return new ReducingSink();}};}?
collect
收集器(Collector)是為Stream.collect()方法量身打造的工具接口(類)。將一個Stream轉(zhuǎn)換成一個容器(或者Map)需要做以下工作:
collect()方法定義為
<R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);三個參數(shù)依次對應(yīng)上述三條分析。不過每次調(diào)用collect()都要傳入這三個參數(shù)太麻煩,收集器Collector就是對這三個參數(shù)的簡單封裝,所以collect()的另一定義為
<R, A> R collect(Collector<? super T, A, R> collector);Collectors工具類可通過靜態(tài)方法生成各種常用的Collector。舉例來說,如果要將Stream規(guī)約成List可以通過如下兩種方式實現(xiàn):
// 將Stream規(guī)約成List Stream<String> stream = Stream.of("I", "love", "you", "too"); List<String> list = stream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);// 方式1 //List<String> list = stream.collect(Collectors.toList());// 方式2 System.out.println(list);通常情況下我們不需要手動指定collect()的三個參數(shù),而是調(diào)用collect(Collector<? super T,A,R> collector)方法,并且參數(shù)中的Collector對象大都是直接通過Collectors工具類獲得。實際上傳入的收集器的行為決定了collect()的行為
生成Collection
Collectors.toList()
Collectors.toSet()
Collectors.toCollection(Supplier<C> collectionFactory)
生成Map
groupingBy()允許我們對元素分組之后再執(zhí)行某種運算,比如求和、計數(shù)、平均值、類型轉(zhuǎn)換等。這種先將元素分組的收集器叫做上游收集器,之后執(zhí)行其他運算的收集器叫做下游收集器(downstream Collector)。
?
總結(jié)
以上是生活随笔為你收集整理的Java8函数式编程(3)--规约操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Java Stream API性能测试
 - 下一篇: Java8函数式编程(4)--终止操作(