如何使用Java Stream API计算List集合对象值的累计和
基于Java Stream实现列表对象数值属性累计和计算
实体类定义
所用实体类结构如下:
public class NameValuePair { private String name; private int value; // 需补充全参构造、getter方法,也可通过Lombok的@Data、@AllArgsConstructor注解自动生成 public NameValuePair(String name, int value) { this.name = name; this.value = value; } public String getName() { return name; } public int getValue() { return value; } }
输入为List<NameValuePair>类型集合,要求返回同类型累计计算结果:集合中每个元素的value值为列表首元素到当前元素的value累计总和。示例输入:("a", 2), ("b", 12), ("c", 15), ("d", 20),对应期望输出:("a", 2), ("b", 14), ("c", 29), ("d", 49)。
实现代码
顺序流场景下可借助AtomicInteger存储累计中间值,规避Lambda表达式对变量final修饰的限制,实现过程不修改原始输入对象,避免副作用:
import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; public class CumulativeSumUtil { public List<NameValuePair> calculateCumulativeSum(List<NameValuePair> sourceList) { AtomicInteger cumulativeSum = new AtomicInteger(0); return sourceList.stream() .map(item -> new NameValuePair( item.getName(), cumulativeSum.addAndGet(item.getValue()) )) .collect(Collectors.toList()); } }
注意事项
- 上述写法仅适用于顺序流场景,如果需要支持并行流,需自定义Collector实现分段累加、多段结果合并的逻辑,否则并行执行时会出现累计值错乱的问题
- 实现中通过生成新
NameValuePair实例的方式构造结果,不会修改原列表中的对象属性,不会污染原始输入数据 - 如果业务允许修改原对象属性,也可直接在map操作中调用原对象的setValue方法更新值后返回,但这种带副作用的写法不推荐使用
执行逻辑验证
用示例输入调用上述方法,执行过程与结果完全匹配预期:
- 处理第一个元素
("a",2):初始累计值0+2=2,生成结果("a",2) - 处理第二个元素
("b",12):当前累计值2+12=14,生成结果("b",14) - 处理第三个元素
("c",15):当前累计值14+15=29,生成结果("c",29) - 处理第四个元素
("d",20):当前累计值29+20=49,生成结果("d",49)
内容的提问来源于stack exchange,提问作者jutatata
相关产品推荐
相关产品推荐

