java8 stream reduce 方法用法 java stream reduce 方法使用方法

一、背景

在使用Stream的reduce方法时,发现该方法有 3个重载方法,分别是: 一个参数、两个参数、三个参数的,那么这3个重载方法的区别和用法呢, 本文将研究3个重载方法之间的区别,理清 一个参数、两个参数、三个参数 的使用场景。

// 一个参数Optional reduce(BinaryOperator accumulator);// 两个参数T reduce(T identity, BinaryOperator accumulator);// 三个参数 U reduce(U identity, BiFunction accumulator, BinaryOperator combiner);

二、相关功能接口理解

1、BiFunction 接口 :

可以看到输入2个参数,输出一个参数

@FunctionalInterfacepublic interface BiFunction {R apply(T t, U u);}

2、BinaryOperator 接口:

具备BiFunction 接口功能,还有2个静态方法 minBy 和 maxBy ,看方法名称作用是:获取最大值和最小值

@FunctionalInterfacepublic interface BinaryOperator extends BiFunction { public static  BinaryOperator minBy(Comparator comparator) {Objects.requireNonNull(comparator);return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;}public static  BinaryOperator maxBy(Comparator comparator) {Objects.requireNonNull(comparator);return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;}}

三、stream reduce 方法代码示例

1、reduce 方法,一个参数:

主要作用 累加、累减,求取最大值、最小值。

@Testpublic void streamReduceOneTest() throws Exception{final ArrayList list = Lists.newArrayList(1, 3, 5, 2, 4);// 累加, 1+3+5+2+4final Optional reduce = list.stream().reduce((x, y) -> x + y);// 累减, 1-3-5-2-4final Optional reduce2 = list.stream().reduce((x, y) -> x - y);System.out.println("reduce x+y ==>" + reduce.orElse(null));System.out.println("reduce2 x-y ==>" + reduce2.orElse(null));// BigDecimal 类型,累加求和final Optional reduce1 = list.stream().map(BigDecimal::new).reduce(BigDecimal::add);System.out.println("BigDecimal add : "+ reduce1.get());// 求取 最大值、最小值final Optional reduce3 = list.stream().reduce(BinaryOperator.maxBy((x, y) -> x - y));final Optional reduce4 = list.stream().reduce(BinaryOperator.maxBy((x, y) -> y - x));System.out.println("max : " + reduce3.get());System.out.println("min : " + reduce4.get());}

1.1、reduce 方法,一个参数,输出结果:

reduce x+y ==>15reduce2 x-y ==>-13BigDecimal add : 15max : 5min : 1

2、reduce 方法,两个参数

主要作用,多了一个初始值,功能同一个参数的

@Testpublic void streamReduceTwoTest() throws Exception {final ArrayList list = Lists.newArrayList(1, 3, 5, 2, 4);// 2个参数,初始化10,一起累加 , 10+1+3+5+2+4final Integer reduce = list.stream().reduce(10, (x, y) -> x + y);// 2个参数,初始化10,一起累减 , 10-1-3-5-2-4final Integer reduce2 = list.stream().reduce(10, (x, y) -> x - y);System.out.println("初始化10,reduce x+y ==>" + reduce);System.out.println("初始化10,reduce2 x-y ==>" + reduce2);// 累乘, 10*1*3*5*2*4final Integer reduce1 = list.stream().reduce(10, (x, y) -> x * y);System.out.println("累积乘法 reduce1 ::: " + reduce1);// 最大值final Integer reduce3 = list.stream().reduce(10, BinaryOperator.maxBy((x, y) -> x - y));System.out.println("最大值: " +reduce3);}

2.1、reduce 方法,两个参数,输出结果:

初始化10,reduce x+y ==>25初始化10,reduce2 x-y ==>-5累积乘法 reduce1 ::: 1200最大值: 10

3、reduce 方法,三个参数:

@Testpublic void streamReduceThreeTest() throws Exception {final ArrayList list = Lists.newArrayList(1, 3, 5, 2, 4);final Integer reduce = list.stream().reduce(20, (x, y) -> x + y, (t, r) -> t - r);System.out.println("reduce 3个参数:"+reduce);final ArrayList strList = Lists.newArrayList("aa", "bb", "cc");// 字符串拼接处理:/** * (x, y) -> x.concat(";").concat(y): *x:初始化 identity 参数 , *y: 集合中的每一个元素 */final String reduce_three_arg = strList.stream().reduce(String.valueOf("reduce three arg: "), (x, y) -> x.concat(";").concat(y), (x, y) -> x);System.out.println("reduce 3个参数 22:"+reduce_three_arg);final String reduce_three_arg2 = strList.stream().reduce(String.valueOf(""), (x, y) -> x.concat(";").concat(y), (x, y) -> x);System.out.println("reduce 3个参数 2222:"+reduce_three_arg2);}

3.1、reduce 方法,三个参数,输出结果:

reduce 3个参数:35reduce 3个参数 22:reduce three arg: ;aa;bb;ccreduce 3个参数 2222:;aa;bb;cc

3.2、可以看到 reduce 在3个参数情况下,第三个参数 BinaryOperator combiner貌似是没啥作用的 … 其实reduce方法三个参数在 并行流 情况下,才会有用 …

4、reduce 方法,三个参数 parallel 并行流

@Testpublic void streamReduceThreeParallelTest() throws Exception {final List list = Lists.newArrayList(1, 2, 3, 4, 5);final Integer reduce = list.stream().reduce(0, (x, y) -> x + y, (x, y) -> x * y);System.out.println(reduce);// 使用 并行流final Integer reduce2 = list.parallelStream().reduce(0, (x, y) -> x + y, (x, y) -> x * y);System.out.println(reduce2);final Integer reduce3 = list.stream().parallel().reduce(0, (x, y) -> x + y, (x, y) -> x * y);System.out.println(reduce3);}

4.1、输出结果:

151201205

四、总结

1、reduce 方法:多个数据,合并为一个数据;主要功能如下:

  • 累积计算,加减乘除等运算,字符串拼接
  • 获取最值,最大值,最小值

2、Sream.max 和 Sream.min 实际调用的就是 reduce 方法

3、reduce 方法3个参数之间的区别

  • 一个参数:多个数据,合并为一个数据
  • 两个参数:比一个参数,多一个identity初始化数据
  • 三个参数:并行流的情况下:第三个参数有用,第二个参数没用非并行流反之 …

遗留问题:reduce 方法3个参数,实际应用场景不确定。并行流,第二个参数失效,非并行流,第三个参数失效的原因 ..