reducing和reduce

简介: reducing和reduce

我的悲伤还来不及出发,就已经到站下车。——《第七天》

java中,分为Collectors.reducingStream#reduce

reduce是减少的意思,此处意为聚合

聚合是聚拢、合并的意思

我们来看看这俩函数的区别吧,下方我用了静态导入:

import java.math.BigDecimal;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.stream.Collector;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;

首先是写法差异,对于只有一个参数的,这个参数指定了我们聚合的操作,此处我做一个累加,返回值为Optional证明有可能不存在值,就没有累加

Optional<Integer> sumOpt = Stream.iterate(0, i -> ++i).limit(10).collect(reducing(Integer::sum));
System.out.println(sumOpt);     // Optional[45]
sumOpt = Stream.iterate(0, i -> ++i).limit(10).reduce(Integer::sum);
System.out.println(sumOpt);     // Optional[45]

两个参数的,这里第一个参数为默认值,这里返回的是默认值+累加后的结果,此处默认值只能指定为相同类型

Integer sum = Stream.iterate(0, i -> ++i).limit(10).collect(reducing(10, Integer::sum));
System.out.println(sum);        // 55
sum = Stream.iterate(0, i -> ++i).limit(10).reduce(10, Integer::sum);
System.out.println(sum);        // 55

到此为止,其实都差不多,下面是三个参数的,这个三参用于聚合为其他类型的默认值,第一个参数还是默认值,第二个参数和第三个参数就有区别了

BigDecimal sumDecimal = Stream.iterate(0, i -> ++i).limit(10).collect(
        reducing(BigDecimal.ZERO, BigDecimal::new, BigDecimal::add));
System.out.println(sumDecimal); // 45
sumDecimal = Stream.iterate(0, i -> ++i).limit(10)
        .reduce(BigDecimal.ZERO, (d, i) -> d.add(new BigDecimal(i)), BigDecimal::add);
System.out.println(sumDecimal); // 45

可以看出我们的Collectors.reducing第二个参数是一个Function,入参为Integer返回值为BigDecimal,并没有进行聚合运算,而是进行了一个转换,此处是由Integer去生成一个BigDecimal,调用的java.math.BigDecimal#BigDecimal(int)这个构造,而第三个参数才是我们的累加操作

Stream#reduce中,第二个参数是一个BiFunction,入参变为两个参数BigDecimal(已经累加的结果,并行流下值不可控)和Integer(本次参与运算的值),返回值为BigDecimal(运算结果),第三个参数是个BinaryOperator只在并行流场景下会用到,之前讲过,这里就不再表了,贴上链接:

reduce补充二

第三个参数区别:

也就是说,我们在串行流中哪怕将Stream#reduce的第三个参数,改为任意操作,他都是不影响结果执行的,例如我们这里取最大值

BigDecimal sumDecimal = Stream.iterate(0, i -> ++i).limit(10).collect(
                reducing(BigDecimal.ZERO, BigDecimal::new, BinaryOperator.maxBy(BigDecimal::compareTo)));
        System.out.println(sumDecimal); // 9
        sumDecimal = Stream.iterate(0, i -> ++i).limit(10)
                .reduce(BigDecimal.ZERO, (d, i) -> d.add(new BigDecimal(i)), BinaryOperator.maxBy(BigDecimal::compareTo));
        System.out.println(sumDecimal); // 45

可以看出,哪怕我们改为BinaryOperator.maxBy(BigDecimal::compareTo),是不影响Stream#reduce的,哪怕我们改为null

BigDecimal sumDecimal = Stream.iterate(0, i -> ++i).limit(10).collect(
        reducing(BigDecimal.ZERO, BigDecimal::new, (l, r) -> null));
System.out.println(sumDecimal); // null
sumDecimal = Stream.iterate(0, i -> ++i).limit(10)
        .reduce(BigDecimal.ZERO, (d, i) -> d.add(new BigDecimal(i)), (l, r) -> null);
System.out.println(sumDecimal); // 45

除非并行流场景下:

Optional<Integer> sumOpt = Stream.iterate(0, i -> ++i).parallel().limit(10).collect(reducing(Integer::sum));
System.out.println(sumOpt);     // Optional[45]
sumOpt = Stream.iterate(0, i -> ++i).parallel().limit(10).reduce(Integer::sum);
System.out.println(sumOpt);     // Optional[45]
Integer sum = Stream.iterate(0, i -> ++i).parallel().limit(10).collect(reducing(10, Integer::sum));
System.out.println(sum);        // 145
sum = Stream.iterate(0, i -> ++i).parallel().limit(10).reduce(10, Integer::sum);
System.out.println(sum);        // 145
BigDecimal sumDecimal = Stream.iterate(0, i -> ++i).parallel().limit(10).collect(
        reducing(BigDecimal.ZERO, BigDecimal::new, (l, r) -> null));
System.out.println(sumDecimal); // null
sumDecimal = Stream.iterate(0, i -> ++i).parallel().limit(10)
        .reduce(BigDecimal.ZERO, (d, i) -> d.add(new BigDecimal(i)), (l, r) -> null);
System.out.println(sumDecimal); // null

我们再次改为求最大值

BigDecimal sumDecimal = Stream.iterate(0, i -> ++i).parallel().limit(10).collect(
        reducing(BigDecimal.ZERO, BigDecimal::new, BinaryOperator.maxBy(BigDecimal::compareTo)));
System.out.println(sumDecimal); // 9
sumDecimal = Stream.iterate(0, i -> ++i).parallel().limit(10)
        .reduce(BigDecimal.ZERO, (d, i) -> d.add(new BigDecimal(i)), BinaryOperator.maxBy(BigDecimal::compareTo));
System.out.println(sumDecimal); // 9

可以看到并行流场景下均生效

相关文章
|
4月前
|
存储 JSON 缓存
reduce学习
reduce学习
|
5月前
|
Python
reduce
【7月更文挑战第11天】
65 0
|
7月前
|
JavaScript 前端开发 索引
|
7月前
|
JavaScript 前端开发 索引
|
7月前
|
分布式计算
MapReduce中的Map和Reduce函数分别是什么作用?
MapReduce中的Map和Reduce函数分别是什么作用?
456 0
|
SQL 缓存 分布式计算
map-reduce执行过程
map-reduce执行过程
139 0
|
分布式计算 资源调度 Java
map-reduce中的组件
map-reduce中的组件
77 0
|
存储 SQL 分布式计算
31 MAPREDUCE的reduce端join算法实现
31 MAPREDUCE的reduce端join算法实现
44 0
|
索引
reduce的介绍及用法
reduce的介绍及用法
147 0
|
前端开发 JavaScript API