一: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组合器的方法主要用在并行操作中。如果你使用了parallelStream reduce操作是并发进行的 为了避免竞争 每个reduce线程都会有独立的result combiner的作用在于合并每个线程的result得到最终结果

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);
123456

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

【Java 8】 Reduce方法的更多相关文章

  1. 【Java 8】Stream通过reduce()方法合并流为一条数据示例

    在本页中,我们将提供 Java 8 Stream reduce()示例. Stream reduce()对流的元素执行缩减.它使用恒等式和累加器函数进行归约. 在并行处理中,我们可以将合并器函数作为附 ...

  2. [五]java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

    reduce-归约 看下词典翻译: 好的命名是自解释的 reduce的方法取得就是其中归纳的含义 java8 流相关的操作中,我们把它理解 "累加器",之所以加引号是因为他并不仅仅 ...

  3. paip.java OutOfMemoryError 解决方法o33

    paip.java OutOfMemoryError 解决方法o33 java.lang.OutOfMemoryError: Requested # java.lang.OutOfMemoryErro ...

  4. JavaScript - reduce方法,reduceRight方法 (Array)

    JavaScript - reduce方法 (Array) 解释:reduce() 方法接收一个函数作为累加器(accumulator),数组 中的每个值(从左到右)开始合并,最终为一个值. 语法:a ...

  5. oracle调用JAVA类的方法

    导入jar包 在oracle中导入需要的jar包,我们把编辑好的java类打成jar包,直接在oarcle里面写简单的调用就可以了,  1.操作系统需要拥有支持loadjava命令的jdk.  2.加 ...

  6. JavaScript数组的reduce方法详解

    数组经常用到的方法有push.join.indexOf.slice等等,但是有一个经常被我们忽略的方法:reduce,这个方法简直强大的不要不要的. 我们先来看看这个方法的官方概述:reduce()  ...

  7. Java中的方法应用

    一.如何定义java中的方法 所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块. 语法: 1. 访问修饰符:方法允许被访问的权限范围, 可以是 public.protected.priv ...

  8. JavaScript中reduce()方法

    原文  http://aotu.io/notes/2016/04/15/2016-04-14-js-reduce/   JavaScript中reduce()方法不完全指南 reduce() 方法接收 ...

  9. Java Runtime.availableProcessors()方法

    Java Runtime.availableProcessors()方法用法实例教程.   描述 java.lang.Runtime.availableProcessors() 方法返回到Java虚拟 ...

随机推荐

  1. Java开发介绍之JDK JRE JVM 和 环境变量配置

    一.JDK>JRE>JVM JDK(Java Development Kit):Java开发工具包 JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和 ...

  2. DASCTF 安恒七月赛wp

    web Ezfileinclude 首页一张图片,看src就可以看出文件包含 验证了时间戳 尝试用php://filter 读源码读不到,以为只能读.jpg,然后用../路径穿越有waf 最后居然一直 ...

  3. 低代码开发,推荐一款Web 端自动化神器:Automa

    1. Automa介绍 又到了优秀工具推荐的时候了,今天给大家分享一款前端自动化操作神器: Automa . 首先了解一下Automa是什么? Automa它定位是一款 Chrome 插件,也就意味着 ...

  4. Windows内核中的CPU架构-8-任务段TSS(task state segment)

    Windows内核中的CPU架构-8-任务段TSS(task state segment) 任务段tss(task state segment)是针对于CPU的一个概念. 举一个简单的例子,你一个电脑 ...

  5. Sqlserver中判断表是否存在

    在sqlserver(应该说在目前所有数据库产品)中创建一个资源如表,视图,存储过程中都要判断与创建的资源是否已经存在  在sqlserver中一般可通过查询sys.objects系统表来得知结果,不 ...

  6. Java 中的关键字

    Java 中有多少个关键字,有大小写之分吗? Java 中有 48 个关键字在使用 + 两个保留关键字未使用,共 50 个关键字. Java 关键字全部都由是小写组成. Java 中保留关键字分别是哪 ...

  7. python一对一教程:Computational Problems for Physics chapter 1-B Code Listings 1.7 - 1.12

    作者自我介绍:大爽歌, b站小UP主 ,直播编程+红警三 ,python1对1辅导老师 . 本博客为一对一辅导学生python代码的教案, 获得学生允许公开. 具体辅导内容为<Computati ...

  8. silky微服务框架服务注册中心介绍

    目录 服务注册中心简介 服务元数据 主机名称(hostName) 服务列表(services) 终结点 时间戳 使用Zookeeper作为服务注册中心 使用Nacos作为服务注册中心 使用Consul ...

  9. [gym102268E]Expected Value

    令$X$为移动次数,答案即$\sum_{i=0}^{\infty}P(X>i)$,后者记作$S_{i}$ 关于$S_{i}$,令$f_{i,j}$表示走了$i$步后位于$j$且未到达过$k$的概 ...

  10. [noi239]count

    将每一个ai表示为$ai=ki\cdot m+ri$,即满足$m\sum ki+\sum ri=n$且$0<ri<m$枚举$S=\sum ri$(S范围是$k\le S\le k(m-1) ...