Java Stream 如何求和
从“算零花钱”到Java Stream求和,新手也能秒懂
你有没有过这样的经历?整理一周的零花钱账单,把每天的金额加起来算总共有多少;或者统计超市购物车里所有商品的总价。换成代码来做这件事,以前可能要写一堆循环、定义变量累加,但现在用Java Stream,几句话就能搞定。今天就用生活里的例子,把Java Stream求和讲得明明白白。
先搞懂:Java Stream是什么?
简单说,它就是Java给的一个“处理数据的工具包”,不管是一堆数字、对象,都能丢进去,用它自带的方法快速处理——比如筛选、排序,或者咱们要的“求和”。就像你整理零花钱,不用一张张数,直接拿个计算器批量算,Stream就是那个“批量处理的计算器”。

举个最常见的例子,比如你有个存着零花钱的列表:List<Integer> pocketMoney = Arrays.asList(10, 20, 15, 5, 30);,要算一周的总零花钱,用循环的话得这么写:
`java
int total = 0;
for (int money : pocketMoney) {
total += money;
}
`
这也不难,但要是数据变多,比如有100条、1000条,循环就显得啰嗦了,而Stream的求和方法,一行就能搞定。
最常用的3种求和方式,对应不同场景
基础数字列表求和:用`mapToInt` + `sum()`
这是最简单的情况,就像上面的零花钱列表,全是整数。Stream的mapToInt能把列表里的元素变成“整数流”,再直接调用sum()方法求和:
`java
int totalMoney = pocketMoney.stream()
.mapToInt(Integer::intValue) // 把包装类转成基本int
.sum();
`
是不是很简单?就像把一堆零钱都换成1元硬币,再直接数总个数。这里的Integer::intValue不用纠结,你可以理解成“把每个零花钱数字拆成能直接加的整数”。
对象列表求和:提取属性再求和
实际开发里,很少直接存纯数字,大多是存对象。比如你有个ShoppingItem类,代表购物车里的商品,有“商品名”和“价格”两个属性,列表是这样的:
`java
class ShoppingItem {
private String name;
private int price;
// 构造方法、getter省略,比如要拿价格就用getPrice()
}
List<ShoppingItem> cart = Arrays.asList(
new ShoppingItem("铅笔", 2),
new ShoppingItem("笔记本", 8),
new ShoppingItem("钢笔", 15)
);
`
现在要算购物车总价,就不能直接转数字了,得先把每个商品的“价格”属性抽出来,再求和:
`java
int totalPrice = cart.stream()
.mapToInt(ShoppingItem::getPrice) // 只提取商品的价格属性
.sum();
`
这就像从一堆商品里,只挑出价格标签,再把标签上的数字加起来,完全不用管商品是啥。
避免空值:处理可能为null的情况
实际中偶尔会遇到空值,比如某一天的零花钱没记录,存成null,这时候直接求和会报错。可以加个过滤,把null去掉,或者给个默认值:
`java
// 方法1:过滤掉null,再求和
int safeTotal = pocketMoney.stream()
.filter(Objects::nonNull) // 去掉null元素
.mapToInt(Integer::intValue)
.sum();
// 方法2:给null补个默认值,比如0
int safeTotal2 = pocketMoney.stream()
.mapToInt(money -> money == null ? 0 : money)
.mapToInt(Integer::intValue)
.sum();
`
这就像整理账单时,遇到没记录的日子,要么跳过不算,要么按0块算,总不会出错。
为啥要学Java Stream求和?
以前用循环求和,代码要写好几行,还容易忘初始化变量(比如漏了int total = 0,结果直接报错)。Stream的方法是官方封装好的,不仅代码短,还能自动处理空值、类型转换这些小问题,就像你用计算器算总价比自己心算不容易错一样。
而且Stream不止能求和,还能同时做其他处理——比如算零花钱时,先把超过20块的金额筛选出来,再求和:
`java
int bigMoneyTotal = pocketMoney.stream()
.filter(m -> m > 20) // 只看超过20的零花钱
.mapToInt(Integer::intValue)
.sum();
`
这就像先把超过20的零花钱挑出来,再算总和,一步就能搞定,不用先筛选再分开循环。
现在再回头看,是不是觉得Java Stream求和没那么难?核心就两步:把数据转成Stream,再用mapToInt把要算的数值抽出来,最后调用sum()就行。遇到空值就加个过滤,对象就先提属性,多试几次就能熟练啦。