如何用Java 8+ Stream遍历嵌套Map结构求和所有value值?
嵌套Map结构的Stream求和实现
正确实现代码
int totalValue = listC.stream() // 提取每个C对象中的ClassB映射表 .map(C::getMap) // 扁平化映射表的values,得到所有ClassB对象的流 .flatMap(classBMap -> classBMap.values().stream()) // 提取每个ClassB对象中的ClassA映射表 .map(ClassB::getMap) // 再次扁平化映射表的values,得到所有ClassA对象的流 .flatMap(classAMap -> classAMap.values().stream()) // 将ClassA对象转换为对应的value值,生成IntStream .mapToInt(ClassA::getValue) // 计算总和 .sum();
代码解析
- 初始流转换:
listC.stream()将List<C>转换为Stream<C>,开启链式处理。 - 提取第一层Map:
map(C::getMap)获取每个C实例中的Map<String, ClassB>,此时流类型为Stream<Map<String, ClassB>>。 - 扁平化第一层Map的values:使用
flatMap替代你之前的collect操作——它会将每个Map的values()转换为Stream<ClassB>,并将所有这些小流合并成一个连续的Stream<ClassB>,避免生成不必要的中间集合。 - 提取第二层Map:
map(ClassB::getMap)获取每个ClassB实例中的Map<String, ClassA>,流类型变为Stream<Map<String, ClassA>>。 - 扁平化第二层Map的values:再次用
flatMap得到所有ClassA对象的流Stream<ClassA>。 - 转换为数值流并求和:
mapToInt(ClassA::getValue)将Stream<ClassA>转换为IntStream(专门处理int类型的流,性能更优),最后调用sum()直接得到总和。
你之前代码的问题
你之前反复使用collect(Collectors.toList()).stream()来转换流,这会在中间步骤创建多个List集合,既增加了内存开销,也让代码变得冗余。Stream设计的核心就是链式无中间集合的数据流处理,flatMap是处理嵌套集合/流场景的最佳工具,它能直接将嵌套结构展平为单层流,无需额外的中间容器。
简化写法(可选)
如果想让代码更简洁,可以把flatMap中的lambda替换为更紧凑的写法:
int totalValue = listC.stream() .map(C::getMap) .flatMap(m -> m.values().stream()) .map(ClassB::getMap) .flatMap(m -> m.values().stream()) .mapToInt(ClassA::getValue) .sum();
内容的提问来源于stack exchange,提问作者emish89
相关产品推荐
相关产品推荐

