Stream reduce 中 Lambda 如何合并结果
在 java stream 的 reduce 操作中,lambda 表达式通过实现 binaryoperator 接口来定义如何将两个元素合并为一个。具体做法是调用 stream.reduce(identity, accumulator, combiner) 三参数版本,其中第三个参数 combiner 是一个接受两个部分结果并返回合并后结果的 lambda 函数。这个合并步骤专门用于并行流(parallel stream)场景,负责将各个线程计算出的局部结果聚合为最终全局结果;对于串行流,该参数会被忽略。

串行与并行流中合并器的行为差异
串行流执行时,reduce 仅使用累加器(accumulator)逐个处理元素,合并器(combiner)不会被调用。而在并行流中,数据被分割成多个子任务,每个子任务先独立计算局部结果,最后必须通过合并器将这些局部结果两两合并,才能得到最终的汇总值。如果省略了合并器,并行流将无法正确聚合结果或抛出异常。

import java.util.stream.Stream;
public class ReduceDemo {
public static void main(String[] args) {
// 示例:计算整数列表的总和
Stream<integer> stream = Stream.of(1, 2, 3, 4, 5);
// 串行模式:只使用累加器,忽略合并器
int serialResult = stream.reduce(0, (a, b) -> a + b, (a, b) -> a + b);
System.out.println("Serial: " + serialResult); // 输出 15
// 并行模式:累加器和合并器都会生效
Stream<integer> parallelStream = Stream.of(1, 2, 3, 4, 5).parallel();
int parallelResult = parallelStream.reduce(
0, // identity: 初始值
(a, b) -> a + b, // accumulator: 累加逻辑
(a, b) -> a + b // combiner: 合并逻辑
);
System.out.println("Parallel: " + parallelResult); // 输出 15
}
}</integer></integer>
自定义对象合并时的具体应用
当 Stream 中的元素是自定义对象时,合并器 Lambda 需要定义如何将两个同类型的对象实例合并。例如,在处理订单流时,可能需要将两个订单对象的金额字段相加,或者将两个列表合并。此时,合并器 Lambda 接收两个部分结果对象作为参数,并返回一个新的合并后的对象或更新后的状态。关键在于确保合并操作满足结合律和交换律(对于非顺序敏感的操作),以保证并行计算的正确性。
import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.List;
class Order {
String id;
double amount;
List<string> items;
Order(String id, double amount, List<string> items) {
this.id = id;
this.amount = amount;
this.items = new ArrayList(items);
}
}
public class CustomReduceDemo {
public static void main(String[] args) {
List<order> orders = List.of(
new Order("A", 10.0, List.of("item1")),
new Order("B", 20.0, List.of("item2"))
);
// 合并所有订单:总金额相加,商品列表合并
Order mergedOrder = orders.parallelStream().reduce(
new Order("total", 0.0, new ArrayList()), // identity
(acc, order) -> { // accumulator
acc.amount += order.amount;
acc.items.addAll(order.items);
return acc;
},
(left, right) -> { // combiner
left.amount += right.amount;
left.items.addAll(right.items);
return left;
}
);
System.out.println("Total Amount: " + mergedOrder.amount); // 30.0
System.out.println("Items Count: " + mergedOrder.items.size()); // 2
}
}</order></string></string>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











