Java8新特性:reduce方法

一:reduce

  • rudece方法:从一个流中生成一个值
  • 三个重载方法:
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);

二:重载方法原理

  • 一个参数
接口继承详情:
Optional<T> reduce(BinaryOperator<T> accumulator);

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
	//两个静态方法,先进行忽略
}

@FunctionalInterface
public interface BiFunction<T, U, R> {
	R apply(T t, U u);
	//一个默认方法,先进行忽略
}

这里可以看出,reduce方法参数为一个函数,返回值为Optional对象,BinaryOperator的作用为规定BiFunction的三个参数泛型类型要一致,也就是说只要我们对apply方法进行实现并传进去就ok了。

文档中写到:

Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value。

大致意思:使用累积函数对此流的元素执行操作,并返回一个描述结果的Optional对象。

reduce方法的效果:
   This is equivalent to:  
        boolean foundAny = false;
        T result = null;
        for (T element : this stream) {
            if (!foundAny) {
                foundAny = true;
                result = element;
            }
            else
                result = accumulator.apply(result, element);
        }
        return foundAny ? Optional.of(result) : Optional.empty();

如上文描述:用T类型对象对流进行遍历,第一个数值进行赋值,其余apply操作,并将操作的结果进行返回,等待下次继续当apply方法参数输入。
那也就是说,我们可以这样:

求和效果展示:
   		List<Integer> num = Arrays.asList(1, 2, 4, 5, 6, 7);
        Integer result = num.stream().reduce((x, y) -> {
            System.out.println("x:"+x);
            return x + y;
        }).get();
        System.out.println("resutl:"+result);
		//你也可以这样写,效果一样,一个为Lambda表达式,一个匿名内部类
	    Integer integer = num.stream().reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer a, Integer b) {

            return a + b;
            }
        }).get();	
  • 两个参数
接口继承详情:

该方法的参数多了一个identity,初始值

T reduce(T identity, BinaryOperator<T> accumulator);

文档解释:

Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value.

大致意思:使用提供的初始值和累计函数对流进行操作,并返回一个初始值类型的计算结果。

     T result = identity;
        for (T element : this stream){
            result = accumulator.apply(result, element)
        }
        return result;

reduce方法效果:使用identity作为初始值,每遍历到一个数据,用apply方法操作并将结果返回。

计和效果展示:
        List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
        Integer result = num.stream().reduce(0,(x, y) -> {
            System.out.println("x:" + x);
            return x + y;
        });
        System.out.println("resutl:" + result);
不同点:①,reduce中多了一个参数,初始值identity。②方法的返回结果为初始值identity类型的对象。
  • 三个参数
接口继承详情:
<U> U reduce(U identity,
               BiFunction<U, ? super T, U> accumulator,
               BinaryOperator<U> combiner);

@FunctionalInterface
public interface BiFunction<T, U, R> {
	R apply(T t, U u);
	//一个默认方法,忽略
}

这里先看一个reduce的参数:①,U类型的初始值。②,(T,U)→U,T+U返回U类型。③组合器,(T,T)→T,T+T返回T类型。

文档描述:

这个是对于combiner组合器的描述,其他描述和前两个方法无二。

The identity value must be an identity for the combiner function.his means that for all u, combiner(identity, u) is equal to code u. Additionally, the code combiner function must be compatible with thecode accumulator function; for all u and t。

大致意思:组合器需要和累加器的返回类型需要进行兼容,combiner组合器的方法主要用在并行操作中。

reduce方法运行效果:
 	   U result = identity;
       for (T element : this stream){
           result = accumulator.apply(result, element)
       }
       return result;
与前两个方法的不同点:

主要是初始值与用于遍历流的对象类型不同,可以进行许多骚操作,例如ArrayList内添加数据,StringBulider拼接数据。

非并行:向ArrayList添加数据:

向arr集合后面添加num集合的数值,由于是非并行操作,combiner组合器方法没有效果,只要参数与返回类型正确即可。

        List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(7);
        arr.add(8);
        arr.add(9);
        arr.add(10);
        List<Integer> reduce = num.stream().reduce(arr, (x, y) -> {
            x.add(y);
            return x;
        }, (List<Integer> x, List<Integer> y) -> {
      	    System.out.println("并行才会出现");
      		return x;
        });
        System.out.println(reduce);
并行:集合内数据求和:
	List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
    Integer num1 = num.parallelStream().reduce(7, (x, y) -> x + y, (x, y)->{
    	System.out.println("这里调用一次"); 
    	return x + y;
    });
    System.out.println(num1);

预算结果应该为1+…+7=28,然而结果为67,那这里应该是这样的,调用6个线程进行计算,每个线程都以7作为初始值进行计算,最后将每个线程进行累计操作。combiner组合器的作用应该大致为将每个线程所计算的结果进行组合。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值