当前位置: 首页 > news >正文

Java Lambda stream reduce

引言

reduce是 Java Stream API 中的一个重要方法,用于将流中的元素反复结合起来,得到一个值。它常用于聚合、累加、拼接等操作。下面是详细说明:

1. 基本语法

有三种常用形式:

1.1 无初始值(返回 Optional)

Optional<T> reduce(BinaryOperator<T> accumulator)
  • 适用于流可能为空的情况,返回Optional<T>
  • accumulator是一个二元函数,接收两个流元素,返回一个合并后的结果。

示例:求最大值

List<Integer> list = Arrays.asList(1, 3, 2, 5, 4); Optional<Integer> max = list.stream().reduce(Integer::max); max.ifPresent(System.out::println); // 输出5

1.2 有初始值(返回 T)

T reduce(T identity, BinaryOperator<T> accumulator)
  • identity是初始值(如0、""等)。
  • 返回类型是 T,流为空时直接返回identity

示例:求和

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int sum = list.stream().reduce(0, Integer::sum); System.out.println(sum); // 输出15

1.3 三参数(并行流用得多)

<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
  • 用于并行流,accumulator负责每个元素的归约,combiner负责合并各线程的结果。

示例:字符串拼接

List<String> list = Arrays.asList("a", "b", "c"); String result = list.stream().reduce( "", (s1, s2) -> s1 + s2, // accumulator (s1, s2) -> s1 + s2 // combiner ); System.out.println(result); // 输出abc

2. 典型用法

求积

int product = Arrays.asList(1, 2, 3, 4).stream().reduce(1, (a, b) -> a * b); System.out.println(product); // 输出24

拼接字符串

String concat = Arrays.asList("a", "b", "c").stream().reduce("", (a, b) -> a + b); System.out.println(concat); // 输出abc

找最小值

Optional<Integer> min = Arrays.asList(5, 2, 8, 1).stream().reduce(Integer::min); min.ifPresent(System.out::println); // 输出1

3. 注意事项

  • 如果流为空,无初始值reduce返回Optional.empty,要注意判空。
  • 有初始值时,结果类型与初始值类型一致,流为空时直接返回初始值。
  • 对于并行流,三参数形式效率更高。
  • reduce适合用于聚合操作,简单计数、求和可直接用countsummaxmin等方法。

4. 高级用法举例

4.1 统计对象属性之和

比如有一个对象列表,统计某个字段的总和:

class Person { String name; int age; // 构造方法和getter略 } List<Person> people = Arrays.asList( new Person("A", 20), new Person("B", 30), new Person("C", 25) ); int totalAge = people.stream() .map(Person::getAge) .reduce(0, Integer::sum); System.out.println(totalAge); // 输出75

4.2 归约为集合(不推荐,推荐用 collect)

虽然可以用 reduce 拼接集合,但推荐用collect。下面是用 reduce 实现:

List<Integer> list = Arrays.asList(1, 2, 3, 4); List<Integer> result = list.stream().reduce( new ArrayList<Integer>(), (acc, item) -> { acc.add(item); return acc; }, (acc1, acc2) -> { acc1.addAll(acc2); return acc1; } ); System.out.println(result); // 输出[1, 2, 3, 4]

注意:这种写法在并行流下可能有线程安全问题,推荐使用collect(Collectors.toList())

4.3 复杂对象归约

比如合并两个对象:

class Stat { int count; int sum; // 构造、getter、setter略 } List<Stat> stats = Arrays.asList( new Stat(1, 10), new Stat(2, 20), new Stat(3, 30) ); Stat total = stats.stream().reduce( new Stat(0, 0), (s1, s2) -> new Stat(s1.count + s2.count, s1.sum + s2.sum) ); System.out.println(total.count); // 输出6 System.out.println(total.sum); // 输出60

5. 常见误区

  1. reduce不是万能的聚合工具
    对于集合归约、分组等复杂操作,优先考虑collect,如Collectors.groupingByCollectors.toList等。

  2. 并行流下要注意可变对象
    如果 identity 是可变对象(如 ArrayList),并行流下可能导致线程安全问题。

  3. 初始值的选择很重要
    初始值应为归约运算的单位元(如加法用0,乘法用1,字符串拼接用"")。


6. 性能建议

  • 对于简单聚合(求和、求最大/最小),用sum()max()min()等内置方法更简洁高效。
  • 对于复杂归约,优先用collect,如Collectors.toList()Collectors.toMap()Collectors.groupingBy()

8. 总结一张表

reduce形式适用场景返回值类型是否可并行
reduce(BinaryOperator)流可能为空Optional
reduce(identity, BinaryOperator)简单聚合T
reduce(identity, accumulator, combiner)并行流复杂归约U

7. 总结

  • reduce可以实现各种聚合、归约操作。
  • 三种常用形式:无初始值、有初始值、三参数(并行流)。
  • 常见场景:求和、求积、拼接、最大/最小值等。
http://www.cnnetsun.cn/news/1333.html

相关文章:

  • Java入门篇,小白有任何不懂的,收藏这篇就够了
  • 对象失业半年多了,Java程序员,IT行业是不是再也找不到工作了
  • Java集合框架全面详解,从小白到精通,收藏这篇就够了
  • 探索Java设计模式:原理、应用与实践,小白到精通,收藏这篇就足够了
  • JavaWeb后端阶段项目,从小白到高级开发,收藏这篇就足够了
  • python运维自动化脚本案例,python自动化运维工具,收藏这篇就够了
  • kafka运维命令大全,零基础入门到精通,收藏这篇就够了
  • 运维简历包装,零基础入门到精通,收藏这篇就够了
  • 服务器SSH没有问题,但是VNC连接失败解决方法,收藏这篇就够了
  • 企业平台化运维能力养成记,零基础入门到精通,收藏这篇就够了
  • mysql日常运维与参数调优,零基础入门到精通,收藏这篇就够了
  • 43岁年纪的系统运维裁员后还能找到运维岗位吗?
  • 37岁前端被裁,深夜刷招聘软件的手都在抖
  • 【Paper2Slides】1:提示词分析:图片生成、内容规划、论文提取
  • 【Paper2Slides】2:图片生成工作逻辑
  • 能用自然语言透明地解释每一步的推理过程‌,彻底打破了传统AI的“黑盒”模式的围棋AI大模型:InternThinke
  • 32 FSMC
  • 单细胞转录组分析流程十一(细胞通讯,cellchat,多个不同细胞的样本)
  • CellChat 原理介绍:从单细胞数据推断细胞通讯的科学方法
  • 最全的ansible自动化运维问题查询指南,零基础入门到精通,收藏这篇就够了
  • 网络运维工程师面试(笔试),零基础入门到精通,收藏这篇就够了
  • mysql 8.0运维与优化,零基础入门到精通,收藏这篇就够了
  • 智能系统运维及常见智能运维系统介绍,零基础入门到精通,收藏这篇就够了
  • Spring Cloud微服务工具集,零基础入门到精通,收藏这篇就够了
  • 对IDC(数据中心)运维了解,零基础入门到精通,收藏这篇就够了
  • 零基础学Linux运维,看这一篇就够了(含30G自学教程笔记)_运维自学
  • 运维之MySQL面试题,零基础入门到精通,收藏这篇就够了
  • 为什么说,运维是IT行业里技术含量最低的?
  • 谁懂啊!七年前端被裁,待业八月仍迷茫
  • OMPS-NPP L2 NP 臭氧 (O3) 垂直剖面条带轨道 NRT