Java8初體驗(二)Stream語法 2

4. 匯聚(Reduce)Stream

在介紹匯聚操作之前,我們先看一下Java doc中對於其定義: 匯聚操作(也稱爲摺疊)接受一個元素序列爲輸入,反覆使用某個合併操作,把序列中的元素合併成一個彙總的結果。比如查找一個數字列表的總和或者最大值,或者把這些數字累積成一個List對象。Stream接口有一些通用的匯聚操作,比如reduce()和collect();也有一些特定用途的匯聚操作,比如sum(),max()和count()。注意:sum方法不是所有的Stream對象都有的,只有IntStream、LongStream和DoubleStream是實例纔有。

可變匯聚:把輸入的元素們累積到一個可變的容器中,比如Collection或者StringBuilder;

  1. 其他匯聚:除去可變匯聚剩下的,一般都不是通過反覆修改某個可變對象,而是通過把前一次的匯聚結果當成下一次的入參,反覆如此。比如reduce,count,allMatch;

4.1 可變匯聚

可變匯聚對應的只有一個方法:collect,正如其名字顯示的,它可以把Stream中的要有元素收集到一個結果容器中(比如Collection)。先看一下最通用的collect方法的定義(還有其他override方法):

1<R> R collect(Supplier<R> supplier,
2                  BiConsumer<R, ? super T> accumulator,
3                  BiConsumer<R, R> combiner);

先來看看這三個參數的含義:Supplier supplier是一個工廠函數,用來生成一個新的容器;BiConsumer accumulator也是一個函數,用來把Stream中的元素添加到結果容器中;BiConsumer combiner還是一個函數,用來把中間狀態的多個結果容器合併成爲一個(併發的時候會用到)。看暈了?來段代碼!

1List<Integer> nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
2    List<Integer> numsWithoutNull = nums.stream().filter(num -> num != null).
3            collect(() -> new ArrayList<Integer>(),
4                    (list, item) -> list.add(item),
5                    (list1, list2) -> list1.addAll(list2));

上面這段代碼就是對一個元素是Integer類型的List,先過濾掉全部的null,然後把剩下的元素收集到一個新的List中。進一步看一下collect方法的三個參數,都是lambda形式的函數(*上面的代碼可以使用方法引用來簡化,留給讀者自己去思考*)。

  • 第一個函數生成一個新的ArrayList實例;

  • 第二個函數接受兩個參數,第一個是前面生成的ArrayList對象,二個是stream中包含的元素,函數體就是把stream中的元素加入ArrayList對象中。第二個函數被反覆調用直到原stream的元素被消費完畢;

  • 第三個函數也是接受兩個參數,這兩個都是ArrayList類型的,函數體就是把第二個ArrayList全部加入到第一個中;

但是上面的collect方法調用也有點太複雜了,沒關係!我們來看一下collect方法另外一個override的版本,其依賴[Collector](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html)。

1<R, A> R collect(Collector<? super T, A, R> collector);

這樣清爽多了!少年,還有好消息,Java8還給我們提供了Collector的工具類–[Collectors](http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html),其中已經定義了一些靜態工廠方法,比如:Collectors.toCollection()收集到Collection中, Collectors.toList()收集到List中和Collectors.toSet()收集到Set中。這樣的靜態方法還有很多,這裏就不一一介紹了,大家可以直接去看JavaDoc。下面看看使用Collectors對於代碼的簡化:

1List<Integer> numsWithoutNull = nums.stream().filter(num -> num != null).
2                collect(Collectors.toList());


原創文章,轉載請註明: 轉載自併發編程網 – ifeve.com本文鏈接地址: Java8初體驗(二)Stream語法詳解

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