Java 8中使用自定义对象作为归约类型创建嵌套Map
解决方案
要实现按loanType和loanCurrency双维度汇总amountPaid与amountRemaining到自定义的MySumObject,你可以通过扩展Collectors.reducing的用法,结合MySumObject的构造与合并逻辑来完成。
步骤1:完善MySumObject的工具方法
首先给MySumObject添加必要的构造方法和合并方法,方便在流操作中转换与汇总:
import java.math.BigDecimal; import java.util.Objects; class MySumObject { BigDecimal paidSum; BigDecimal remainingSum; // 初始化零值的空构造 public MySumObject() { this.paidSum = BigDecimal.ZERO; this.remainingSum = BigDecimal.ZERO; } // 从MyObject转换的构造方法(处理可能的null值) public MySumObject(MyObject obj) { this.paidSum = Objects.requireNonNullOrDefault(obj.getAmountPaid(), BigDecimal.ZERO); this.remainingSum = Objects.requireNonNullOrDefault(obj.getAmountRemaining(), BigDecimal.ZERO); } // 合并另一个MySumObject的方法 public MySumObject merge(MySumObject other) { this.paidSum = this.paidSum.add(other.paidSum); this.remainingSum = this.remainingSum.add(other.remainingSum); return this; } // 可选:添加getter/setter方便后续访问 public BigDecimal getPaidSum() { return paidSum; } public BigDecimal getRemainingSum() { return remainingSum; } }
步骤2:修改流收集逻辑
将原有的单金额汇总逻辑,替换为针对MySumObject的双金额汇总:
import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<MyObject> list1 = // 你的MyObject列表 Map<String, Map<String, MySumObject>> result = list1.stream().collect( // 第一级分组:按loanType Collectors.groupingBy(MyObject::getLoanType, // 第二级分组:按loanCurrency Collectors.groupingBy(MyObject::getLoanCurrency, // 汇总逻辑:将MyObject转换为MySumObject并合并 Collectors.reducing( new MySumObject(), // 初始汇总对象(零值) MySumObject::new, // 将单个MyObject转为MySumObject MySumObject::merge // 合并两个MySumObject的金额 ) ) ) ); } }
逻辑说明
- 分组层级:外层按
loanType分组,内层按loanCurrency分组,确保每个(loanType, loanCurrency)组合对应唯一的汇总对象。 - 汇总逻辑:
new MySumObject():提供初始的零值汇总对象,作为合并的起点。MySumObject::new:将每个MyObject转换为包含对应金额的MySumObject实例。MySumObject::merge:把多个MySumObject的paidSum和remainingSum分别累加,得到最终的汇总结果。
额外注意事项
如果你的MyObject中amountPaid或amountRemaining可能为null,一定要在转换时用Objects.requireNonNullOrDefault兜底,避免NullPointerException。
内容的提问来源于stack exchange,提问作者jasmeet
相关产品推荐
相关产品推荐

