You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中对Map<String, List<Obj>>内BigDecimal求和的优雅实现方案求助

优雅实现Map<String, List>中所有Obj的BigDecimal属性求和(Java Streams版)

嘿,这个需求用Java Streams确实能写出非常简洁优雅的代码,我来给你分享几种靠谱的实现方式,都是我日常开发里常用的:

基础实现(假设getB不会返回null)

如果你的Obj.getB()方法保证不会返回null,那这段代码就足够简洁:

BigDecimal total = myMap.values()
    .stream()
    // 将所有嵌套的List<Obj>扁平化为单个Obj的流,避免嵌套循环
    .flatMap(List::stream)
    // 提取每个Obj的BigDecimal属性b
    .map(Obj::getB)
    // 从BigDecimal.ZERO开始,依次累加所有值
    .reduce(BigDecimal.ZERO, BigDecimal::add);

代码解释:

  • myMap.values():先拿到Map中所有的List<Obj>集合
  • flatMap(List::stream):把多个List拆成连续的Obj流,这是处理嵌套集合的关键一步
  • map(Obj::getB):将每个对象转换为我们需要求和的BigDecimal属性
  • reduce(BigDecimal.ZERO, BigDecimal::add):BigDecimal没有Stream默认的sum()方法,所以用reduce来实现累加,初始值必须设为BigDecimal.ZERO,否则空流会返回null

安全实现(处理getB可能返回null的情况)

如果getB()有可能返回null,一定要加上过滤逻辑,避免抛出NullPointerException:

import java.util.Objects;

BigDecimal total = myMap.values()
    .stream()
    .flatMap(List::stream)
    .map(Obj::getB)
    // 过滤掉所有null值,确保后续add操作安全
    .filter(Objects::nonNull)
    .reduce(BigDecimal.ZERO, BigDecimal::add);

另一种风格:用Collectors.reducing收集器

如果你更喜欢用收集器的写法,也可以这样实现,效果完全相同:

import java.util.stream.Collectors;

BigDecimal total = myMap.values()
    .stream()
    .flatMap(List::stream)
    .collect(Collectors.reducing(
        BigDecimal.ZERO,  // 初始值
        Obj::getB,        // 提取属性的函数
        BigDecimal::add   // 累加逻辑
    ));

这几种写法都完全摒弃了传统的嵌套循环,用流式API实现了声明式的求和逻辑,代码简洁易读,非常符合Java 8+的优雅编码风格。

内容的提问来源于stack exchange,提问作者user2220232

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:13:56