跳转至

Java Stream API — reduce(identity, accumulator) 使用总结

📌 方法定义

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

该方法对流中的元素执行归约操作,使用指定的 恒等值 identity 和一个 结合型累加函数 accumulator,返回归约后的结果。

其逻辑等价于:

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

⚙️ 并行执行说明

✅ 用户无需关心的并行实现细节:

  • 数据的分片策略
  • 并行任务的线程调度
  • 中间结果的合并过程
  • 所使用的线程池或底层机制(如 ForkJoinPool)

这些由 Java 流的实现自动处理,特别是在调用 .parallel() 时。

⚠️ 但必须满足的前提条件:

要求 说明
结合性 (Associativity) a ⊕ (b ⊕ c) == (a ⊕ b) ⊕ c,如加法、乘法、字符串拼接
无副作用 (Stateless & Non-interfering) 累加函数不能访问或修改外部状态或共享变量
恒等值 identity 对所有 t 满足:accumulator.apply(identity, t) == t

💡 使用示例

示例 1:整数求和

List<Integer> integers = List.of(1, 2, 3, 4);
Integer sum = integers.reduce(0, Integer::sum);
System.out.println(sum); // 输出 10

示例 2:字符串拼接

List<String> words = List.of("Hello", "World");
String sentence = words.reduce("", (a, b) -> a + " " + b);
System.out.println(sentence); // 输出 " Hello World"

✅ 优点总结

  • 提供函数式风格的聚合操作
  • 可自动并行执行,适合大数据量处理
  • 避免线程安全问题,简化同步逻辑

⚠️ 错误示例:含副作用的累加器

List<Integer> list = Arrays.asList(1, 2, 3);

// 不推荐:累加器包含副作用操作(打印),并行执行可能导致混乱
Integer sum = list.parallelStream().reduce(0, (a, b) -> {
    System.out.println(Thread.currentThread().getName());
    return a + b;
});

输出结果可能无序,性能不稳定,并可能出现竞态条件。


🔚 总结

reduce(identity, accumulator) 是一种强大而安全的终端归约操作。
只要满足函数式约束(结合性、无副作用、恒等值),你就可以放心地使用它进行顺序或并行的聚合处理,而无需操心底层并发细节。

回到页面顶部