java stream的reduce用于函数式归约,有三种重载:无初始值(返回optional)、带中性初始值、三参数(含combiner,支持并行);需满足结合律与不可变性。

Java Stream 的 reduce 算子用于将流中元素通过二元操作逐步合并为一个结果,适合实现自定义累加、归约(如求和、拼接、最大值、对象聚合等)。它不是简单循环替代,而是强调不可变性与函数式语义,需注意初始值、累积逻辑与并行安全性。
理解 reduce 的三种重载形式
reduce 提供三个常用签名,适用不同场景:
-
无初始值(Optional 结果):适用于非空流,返回
Optional<t></t>,若流为空则为empty() - 带初始值(identity):提供中性元素(如 0 对加法、1 对乘法、"" 对字符串拼接),结果类型与元素类型一致
- 三参数(并行友好):含 identity、accumulator 和 combiner,支持并行流正确归约,尤其用于可变对象或复杂类型
基础数值累加:用带初始值的 reduce
对整数流求和是最直观例子。初始值选 0,累加器用 (a, b) -> a + b:
List<integer> numbers = Arrays.asList(1, 2, 3, 4); int sum = numbers.stream().reduce(0, (a, b) -> a + b); // 结果:10 </integer>
⚠️ 注意:此处 lambda 必须满足 结合律((a+b)+c == a+(b+c)),否则并行执行可能出错;加法满足,但减法不满足,不能直接用 (a,b)->a-b。
对象属性累加:如统计订单总金额
假设有 Order 类,需累加所有订单的 amount 字段:
class Order { double amount; /* 构造/Getter 略 */ }
List<order> orders = ...;
double total = orders.stream()
.reduce(0.0, (sum, order) -> sum + order.getAmount(), Double::sum);
</order>这里第三参数 Double::sum 是 combiner,在并行流中用于合并各分段结果(如线程 A 算出 100.0,B 算出 85.5,最终调用 100.0 + 85.5)。即使串行也建议写全,保证代码可扩展性。
构建复合结果:用三参数 reduce 聚合多个统计值
若需同时计算「元素个数」和「总和」,可定义容器类并安全归约:
record Stats(long count, double sum) {
Stats combine(Stats other) {
return new Stats(this.count + other.count, this.sum + other.sum);
}
}
List<double> values = Arrays.asList(1.5, 2.5, 3.0);
Stats result = values.stream()
.reduce(new Stats(0, 0.0),
(stats, v) -> new Stats(stats.count + 1, stats.sum + v),
(s1, s2) -> s1.combine(s2));
// result = Stats[count=3, sum=7.0]
</double>关键点:
• identity 必须是中性元素(不影响结果),此处 new Stats(0, 0.0) 满足
• accumulator 处理单个元素,生成新对象(不可变)
• combiner 合并两个中间结果,必须满足 combiner.apply(a, b) == combiner.apply(b, a) 且与 accumulator 兼容
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











