如何用Java Stream处理嵌套Map?求实现方案
解决方案
要实现嵌套Map下的逻辑,核心是先遍历外层Map的SKU-渠道条目,再针对每个条目匹配对应的事实数据内层Map,最后过滤出事实中不存在的日期并累加预算值。以下是完整实现:
import java.math.BigDecimal; import java.time.LocalDate; import java.util.Collections; import java.util.Map; // 假设SKUIdCanalIdDTO、SKUIdCanalId、Budget、Measure类已定义 private static BigDecimal getValueBudgetUnrealized(Map<SKUIdCanalIdDTO, Map<LocalDate, BigDecimal>> factByMonth, Map<SKUIdCanalId, Map<LocalDate, Budget>> budgetByMonth, Measure measure) { return budgetByMonth.entrySet().stream() .flatMap(budgetSkuEntry -> { SKUIdCanalId budgetSkuKey = budgetSkuEntry.getKey(); Map<LocalDate, Budget> budgetDateMap = budgetSkuEntry.getValue(); // 匹配事实数据中对应的SKU-渠道内层Map,不存在则用空Map // 注意:需确保SKUIdCanalId与SKUIdCanalIdDTO可正确匹配(equals/hashCode一致或转换) Map<LocalDate, BigDecimal> factDateMap = factByMonth.get(/* 若需转换则写转换逻辑,比如new SKUIdCanalIdDTO(budgetSkuKey) */ budgetSkuKey); factDateMap = factDateMap == null ? Collections.emptyMap() : factDateMap; // 过滤事实中不存在的日期,映射为预算值 return budgetDateMap.entrySet().stream() .filter(dateEntry -> !factDateMap.containsKey(dateEntry.getKey())) .map(dateEntry -> dateEntry.getValue().getValueByMeasure(measure)); }) // 累加所有符合条件的预算值 .reduce(BigDecimal.ZERO, BigDecimal::add); }
关键说明
- 外层键匹配:必须保证
SKUIdCanalId和SKUIdCanalIdDTO能正确匹配,若为不同类,需基于业务标识实现equals()和hashCode(),或在获取事实Map时做类型转换。 - 空值处理:如果事实数据中没有对应SKU-渠道的条目,该渠道下所有预算日期都会被纳入累加。
- 流操作逻辑:用
flatMap将两层嵌套的流合并为单层,延续了你在单层Map示例中的过滤、映射、累加逻辑,保持代码风格一致。
内容的提问来源于stack exchange,提问作者jcolrs
相关产品推荐
相关产品推荐

