1. 简介
在本篇教程中,我们将介绍使用 Java Stream API 对整数列表进行求和的各种方法。
虽然示例中我们以整型(Integer
)为主,但同样的思路也适用于 Long
和 Double
类型的数据。
2. 使用 Stream.reduce()
Stream.reduce()
是一个终端操作,用于对流中的元素执行归约操作。
它接收一个二元操作符(累加器),将流中每个元素依次与前一次的结果进行运算。第一个操作数是初始值或上一次的计算结果,第二个则是当前元素。
✅ 最基础的方式:Lambda 表达式
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
.reduce(0, (a, b) -> a + b);
✅ 更优雅的方式:使用内置方法引用
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
.reduce(0, Integer::sum);
✅ 自定义方法引用
我们也可以定义自己的加法函数:
public class ArithmeticUtils {
public static int add(int a, int b) {
return a + b;
}
}
然后通过方法引用来调用:
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
.reduce(0, ArithmeticUtils::add);
⚠️ 小贴士:如果只是简单的加法,推荐直接使用 Integer::sum
,没必要造轮子。
3. 使用 Stream.collect()
另一种常用的求和方式是结合 Collectors
工具类中的 summingInt()
方法:
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
.collect(Collectors.summingInt(Integer::intValue));
类似地,Collectors
还提供了 summingLong()
和 summingDouble()
来处理长整型和浮点型数据。
4. 使用 IntStream.sum()
Stream API 提供了 mapToInt()
这个中间操作,可以将普通 Stream 转换为 IntStream
,之后就可以直接调用 sum()
方法:
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
.mapToInt(Integer::intValue)
.sum();
同理,还有 mapToLong()
和 mapToDouble()
可供选择。
5. 处理 Map 中的值求和
假设我们有一个 Map<Object, Integer>
结构,要对其 value 求和,可以先获取 values 流,再进行求和操作:
Integer sum = map.values()
.stream()
.mapToInt(Integer::valueOf)
.sum();
6. 对象字段求和
假设我们有如下对象:
public class Item {
private int id;
private Integer price;
public Item(int id, Integer price) {
this.id = id;
this.price = price;
}
// Standard getters and setters
}
并创建了一个列表:
Item item1 = new Item(1, 10);
Item item2 = new Item(2, 15);
Item item3 = new Item(3, 25);
Item item4 = new Item(4, 40);
List<Item> items = Arrays.asList(item1, item2, item3, item4);
要计算所有 price
字段的总和,我们需要先使用 map()
提取出 price 值,再进行求和:
使用 reduce + 方法引用
Integer sum = items.stream()
.map(x -> x.getPrice())
.reduce(0, Integer::sum);
使用 reduce + Lambda
Integer sum = items.stream()
.map(item -> item.getPrice())
.reduce(0, (a, b) -> a + b);
使用 collect + Collectors.summingInt
Integer sum = items.stream()
.map(x -> x.getPrice())
.collect(Collectors.summingInt(Integer::intValue));
推荐方式:使用 mapToInt + sum()
Integer sum = items.stream()
.mapToInt(x -> x.getPrice())
.sum();
✅ 简单粗暴,性能也最优。
7. 字符串中提取数字求和
如果我们有一个字符串包含数字,比如:
String string = "Item1 10 Item2 25 Item3 30 Item4 45";
我们可以通过以下步骤完成求和:
- 分割字符串为数组;
- 过滤出纯数字字符串;
- 转换为整数;
- 求和;
代码如下:
Integer sum = Arrays.stream(string.split(" "))
.filter((s) -> s.matches("\\d+"))
.mapToInt(Integer::valueOf)
.sum();
⚠️ 注意正则表达式 \d+
匹配的是一个或多个数字字符。
8. 总结
在这篇文章中,我们探讨了多种使用 Java Stream API 对整数列表求和的方法,并将其扩展到以下场景:
- 对象字段求和;
- Map 值求和;
- 字符串中数字提取并求和;
这些方法在实际开发中非常常见,掌握它们能让你写出更简洁高效的代码。
📌 完整代码示例可在 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-streams