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 collect(Supplier supplier,
2                   BiConsumersuper T> accumulator,
3                   BiConsumer combiner);

先来看看这三个参数的含义:Supplier supplier是一个工厂函数,用来生成一个新的容器;BiConsumer accumulator也是一个函数,用来把Stream中的元素添加到结果容器中;BiConsumer combiner还是一个函数,用来把中间状态的多个结果容器合并成为一个(并发的时候会用到)。看晕了?来段代码!

1 List nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
2     List numsWithoutNull = nums.stream().filter(num -> num != null).
3             collect(() -> new ArrayList(),
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 collect(Collectorsuper 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对于代码的简化:

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


原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Java8初体验(二)Stream语法详解