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

HashMap移除金额为0的记录失败,求排查代码问题

问题原因及解决方案

为什么现有代码不生效?

问题出在BigDecimal的equals方法上:equals()不仅比较数值,还会校验精度(比如小数点后的位数)。你的日志里显示的是totalAmount: 0.00,而BigDecimal.ZERO是精度为0的0,所以new BigDecimal("0.00").equals(BigDecimal.ZERO)会返回false——过滤逻辑没匹配到这些值为0的条目,自然removeAll也无法移除对应的key。

修复方案

方案1:原地修改现有HashMap(无需新建)

把过滤条件里的equals换成compareTo,只比较数值大小:

logger.info("Size of the caseTotal before processing is " + caseTotals.size()) ;

// 改用compareTo判断BigDecimal数值是否为0
caseTotals.keySet().removeAll(
    caseTotals.entrySet().stream()
        .filter(a -> a.getValue().compareTo(BigDecimal.ZERO) == 0)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList())
);

caseTotals.forEach((k,v)->logger.info("case number: " + k + ", totalAmount: " + v.toString()));      
logger.info("Size of the caseTotal after processing is " + caseTotals.size()) ;

方案2:新建HashMap存储过滤后的结果(更安全)

如果需要保留原Map,或者担心并发修改问题,推荐这种方式:

logger.info("Size of the caseTotal before processing is " + caseTotals.size()) ;

// 新建Map存储非0的条目
Map<String, BigDecimal> filteredCaseTotals = caseTotals.entrySet().stream()
    .filter(entry -> entry.getValue().compareTo(BigDecimal.ZERO) != 0)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

filteredCaseTotals.forEach((k,v)->logger.info("case number: " + k + ", totalAmount: " + v.toString()));      
logger.info("Size of the caseTotal after processing is " + filteredCaseTotals.size()) ;

补充说明

  • 原地修改时,keySet().removeAll()是合法操作,HashMap的keySet是原Map的视图,修改keySet会同步修改原Map;你当前的写法是先收集所有待删除key再批量删除,不会触发并发修改异常。
  • 用compareTo是BigDecimal数值比较的标准做法,能彻底避免精度差异带来的匹配失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 18:45:16