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

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

一、背景

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

// 一个参数
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);

二、相关功能接口理解

        1、BiFunction 接口 :

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

@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u);
}

        2、BinaryOperator 接口:

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

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

    
    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }
}

三、stream reduce 方法代码示例

        1、reduce 方法,一个参数:

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

@Test
public void streamReduceOneTest() throws Exception{
    final ArrayList<Integer> list = Lists.newArrayList(1, 3, 5, 2, 4);
    // 累加, 1+3+5+2+4
    final Optional<Integer> reduce = list.stream().reduce((x, y) -> x + y);
    // 累减, 1-3-5-2-4
    final Optional<Integer> 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<BigDecimal> reduce1 = list.stream().map(BigDecimal::new).reduce(BigDecimal::add);
    System.out.println("BigDecimal add : "+ reduce1.get());

    // 求取 最大值、最小值
    final Optional<Integer> reduce3 = list.stream().reduce(BinaryOperator.maxBy((x, y) -> x - y));
    final Optional<Integer> 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 ==>15
reduce2 x-y ==>-13
BigDecimal add : 15
max : 5
min : 1

        2、reduce 方法,两个参数

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

@Test
public void streamReduceTwoTest() throws Exception {
    final ArrayList<Integer> list = Lists.newArrayList(1, 3, 5, 2, 4);

    // 2个参数,初始化10,一起累加 , 10+1+3+5+2+4
    final Integer reduce = list.stream().reduce(10, (x, y) -> x + y);

    // 2个参数,初始化10,一起累减 , 10-1-3-5-2-4
    final 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*4
    final 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 方法,三个参数:

@Test
public void streamReduceThreeTest() throws Exception {
    final ArrayList<Integer> 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<String> 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个参数:35
reduce 3个参数 22:reduce three arg: ;aa;bb;cc
reduce 3个参数 2222:;aa;bb;cc

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

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

@Test
public void streamReduceThreeParallelTest() throws Exception {
    final List<Integer> 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、输出结果:

15
120
120
5

四、总结

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

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

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

 

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

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

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

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年12月19日
下一篇 2023年12月19日

相关推荐