Java中使用Lambda计算嵌套Map内MyObject的field1总和方法
嘿,我来帮你搞定这个Java Lambda求和的问题!首先咱们先把基础场景理清楚——你说的嵌套Map,大概率是两层嵌套结构(比如Map<外层Key, Map<内层Key, List<MyObject>>>),或者也可能是单层的Map<Key, List<MyObject>>?不管哪种,用Java 8+的Stream API配合Lambda都能轻松实现,下面分场景给你具体方案:
先定义基础类MyObject
首先咱们先把MyObject类的结构明确下来,方便后续代码演示:
class MyObject { private int field1; // 构造器、Getter方法 public MyObject(int field1) { this.field1 = field1; } public int getField1() { return field1; } }
场景1:单层Map(Map<Key, List>)
如果你的结构是一个Map直接对应Listfield1的总和,最终得到一个Map<Key, Integer>(Key保留原Map的键,值对应总和),代码实现如下:
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class SumDemo { public static void main(String[] args) { // 初始化测试数据 Map<String, List<MyObject>> myMap = new HashMap<>(); myMap.put("小组A", Arrays.asList(new MyObject(1), new MyObject(2), new MyObject(3))); myMap.put("小组B", Arrays.asList(new MyObject(4), new MyObject(5))); // 核心求和逻辑 Map<String, Integer> sumResultMap = myMap.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, // 保留原Map的Key entry -> entry.getValue().stream() .mapToInt(MyObject::getField1) // 把每个MyObject转成field1的int值 .sum() // 对int流求和 )); // 打印结果验证 sumResultMap.forEach((key, sum) -> System.out.println(key + "的field1总和:" + sum)); // 输出: // 小组A的field1总和:6 // 小组B的field1总和:9 } }
逻辑解释:
- 用
entrySet().stream()把Map转换成Entry流,方便同时操作Key和Value; - 用
Collectors.toMap()收集结果,第一个参数保留原Key,第二个参数对每个List做求和; mapToInt(MyObject::getField1)是方法引用,等价于Lambda表达式obj -> obj.getField1(),把对象转成int值;- 最后调用
sum()对int流求和,非常高效。
场景2:嵌套Map(Map<外层Key, Map<内层Key, List>>)
如果是两层嵌套的Map结构,想要计算最内层每个List的field1总和,最终得到Map<外层Key, Map<内层Key, Integer>>,只需要在上面的基础上嵌套一层Stream处理即可:
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class NestedSumDemo { public static void main(String[] args) { // 初始化嵌套Map的测试数据 Map<String, Map<Integer, List<MyObject>>> nestedMap = new HashMap<>(); Map<Integer, List<MyObject>> innerMap1 = new HashMap<>(); innerMap1.put(1, Arrays.asList(new MyObject(10), new MyObject(20))); innerMap1.put(2, Arrays.asList(new MyObject(30))); nestedMap.put("部门1", innerMap1); Map<Integer, List<MyObject>> innerMap2 = new HashMap<>(); innerMap2.put(1, Arrays.asList(new MyObject(5), new MyObject(5), new MyObject(5))); nestedMap.put("部门2", innerMap2); // 核心嵌套求和逻辑 Map<String, Map<Integer, Integer>> nestedSumResult = nestedMap.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, // 保留外层Map的Key outerEntry -> outerEntry.getValue().entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, // 保留内层Map的Key innerEntry -> innerEntry.getValue().stream() .mapToInt(MyObject::getField1) .sum() )) )); // 打印结果验证 nestedSumResult.forEach((outerKey, innerSumMap) -> { System.out.println("外层Key:" + outerKey); innerSumMap.forEach((innerKey, sum) -> System.out.println(" 内层Key " + innerKey + "的总和:" + sum)); }); // 输出: // 外层Key:部门1 // 内层Key 1的总和:30 // 内层Key 2的总和:30 // 外层Key:部门2 // 内层Key 1的总和:15 } }
逻辑解释:
和单层Map的思路一致,只是在外层Stream的处理中,再对每个内层Map做一次相同的Stream求和操作,嵌套使用Collectors.toMap()即可。
额外健壮性优化:处理空List或Null值
如果你的List可能为空,甚至Map的Value可能为Null,为了避免NullPointerException,可以在求和逻辑里加个判断:
// 把求和的Lambda改成下面这样 innerEntry -> innerEntry.getValue() != null ? innerEntry.getValue().stream().mapToInt(MyObject::getField1).sum() : 0
这样即使List为Null或者为空,都会返回0,避免程序崩溃。
内容的提问来源于stack exchange,提问作者WomenWhoCode
相关产品推荐
相关产品推荐

