Stream API为我们提供了Stream.reduce用来实现集合元素的归约。reduce函数有三个参数:

  • Identity标识:一个元素,它是归约操作的初始值,如果流为空,则为默认结果。
  • Accumulator累加器:具有两个参数的函数:归约运算的部分结果和流的下一个元素。
  • Combiner合并器(可选):当归约并行化时,或当累加器参数的类型与累加器实现的类型不匹配时,用于合并归约操作的部分结果的函数。



    注意观察上面的图,我们先来理解累加器:
  • 阶段累加结果作为累加器的第一个参数
  • 集合遍历元素作为累加器的第二个参数

Integer类型归约

reduce初始值为0,累加器可以是lambda表达式,也可以是方法引用。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
int result = numbers
.stream()
.reduce(0, (subtotal, element) -> subtotal + element);
System.out.println(result); //21 int result = numbers
.stream()
.reduce(0, Integer::sum);
System.out.println(result); //21

String类型归约

不仅可以归约Integer类型,只要累加器参数类型能够匹配,可以对任何类型的集合进行归约计算。

List<String> letters = Arrays.asList("a", "b", "c", "d", "e");
String result = letters
.stream()
.reduce("", (partialString, element) -> partialString + element);
System.out.println(result); //abcde String result = letters
.stream()
.reduce("", String::concat);
System.out.println(result); //ancde

复杂对象归约

计算所有的员工的年龄总和。

Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
Employee e2 = new Employee(2,13,"F","Martina","Hengis");
Employee e3 = new Employee(3,43,"M","Ricky","Martin");
Employee e4 = new Employee(4,26,"M","Jon","Lowman");
Employee e5 = new Employee(5,19,"F","Cristine","Maria");
Employee e6 = new Employee(6,15,"M","David","Feezor");
Employee e7 = new Employee(7,68,"F","Melissa","Roy");
Employee e8 = new Employee(8,79,"M","Alex","Gussin");
Employee e9 = new Employee(9,15,"F","Neetu","Singh");
Employee e10 = new Employee(10,45,"M","Naveen","Jain"); List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); Integer total = employees.stream().map(Employee::getAge).reduce(0,Integer::sum);
System.out.println(total); //346
  • 先用map将Stream流中的元素由Employee类型处理为Integer类型(age)。
  • 然后对Stream流中的Integer类型进行归约

Combiner合并器的使用

除了使用map函数实现类型转换后的集合归约,我们还可以用Combiner合并器来实现,这里第一次使用到了Combiner合并器。

因为Stream流中的元素是Employee,累加器的返回值是Integer,所以二者的类型不匹配。这种情况下可以使用Combiner合并器对累加器的结果进行二次归约,相当于做了类型转换。

Integer total3 = employees.stream()
.reduce(0,(totalAge,emp) -> totalAge + emp.getAge(),Integer::sum); //注意这里reduce方法有三个参数
System.out.println(total); //346

计算结果和使用map进行数据类型转换的方式是一样的。

并行流数据归约(使用合并器)

对于大数据量的集合元素归约计算,更能体现出Stream并行流计算的威力。

在进行并行流计算的时候,可能会将集合元素分成多个组计算。为了更快的将分组计算结果累加,可以使用合并器。

Integer total2 = employees
.parallelStream()
.map(Employee::getAge)
.reduce(0,Integer::sum,Integer::sum); //注意这里reduce方法有三个参数 System.out.println(total); //346

欢迎关注我的博客,里面有很多精品合集

  • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

最新文章

  1. android Gui系统之SurfaceFlinger(4)---Vsync(1)
  2. 【Oracle XE系列之一】Windows10_X64环境 安装Oracle XE11gR2 X64数据库
  3. 模拟赛1030d1
  4. Node.js 文件系统
  5. ASP.NET HttpRuntime.Cache缓存类使用总结
  6. pandas groupby
  7. 转摘http://blog.csdn.net/hulihui/article/details/3351922#s6
  8. android学习笔记八——SeekBar
  9. ON、WHERE、HAVING的区别
  10. linux下文件夹的创建、复制、剪切、重命名、清空和删除命令
  11. Prototype 模式
  12. 【HDOJ】3442 Three Kingdoms
  13. 请阐述调用Activity有哪几种方法,并写出相关的Java代码
  14. 目测ZIP的压缩率
  15. 间隔DP基础 POJ2955——Brackets
  16. tinyxml 查找element
  17. SFTP环境搭建及客户代码调用公共方法封装
  18. 计算机网络之TCP协议与UDP协议
  19. iOS应用启动时间
  20. ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

热门文章

  1. Java实现 LeetCode 706 设计哈希映射(数组+链表)
  2. Java实现 蓝桥杯VIP 算法训练 字符删除
  3. 第八届蓝桥杯JavaB组国(决)赛真题
  4. Java实现蓝桥杯互补二元组
  5. java实现第三届蓝桥杯DNA对比
  6. 逐行解读HashMap源码
  7. Spring 源码学习 - 单例bean的实例化过程
  8. 描述一下 JVM 加载 class 文 件的原理机制?
  9. render props的运用
  10. jenkins环境安装(windows)