最常用方式是map.values().stream().maptoint(integer::intvalue).sum(),适用于integer型value且非null;含null需filter或三元运算处理,hashmap/treemap不影响求和结果,但并发需用concurrenthashmap,性能敏感时传统循环更优。

Map.values() 后直接用 stream().mapToInt().sum() 最常用
Java 8+ 中统计 Map 所有 value 的数值和,最直白的方式就是先取值集合,再走流式计算。前提是所有 value 是数字类型(如 Integer、Long),且不为 null。
-
map.values().stream().mapToInt(Integer::intValue).sum()—— 适用于Map<k integer></k> -
map.values().stream().mapToLong(Long::longValue).sum()—— 适用于Map<k long></k>,避免int溢出 - 如果
value是Number子类(比如Double或自定义包装类),不能直接用mapToInt,得先map成基本类型再转,否则编译失败 - 空
Map时返回0,安全;但含null值会抛NullPointerException
遇到 null value 怎么办:filter + mapToInt
线上代码常有未校验的 null 值,直接调 mapToInt 会崩。必须提前过滤或做非空转换。
- 加
.filter(Objects::nonNull):例如map.values().stream().filter(Objects::nonNull).mapToInt(Integer::intValue).sum() - 若想把
null当0处理,改用.mapToInt(v -> v == null ? 0 : v.intValue()) - 注意
Objects::nonNull只判引用是否为空,不处理Integer.valueOf(0)这类“逻辑零值” - 别用
Optional.ofNullable(v).map(...).orElse(0)套娃——性能差,且mapToInt不接受Optional
Map 是 HashMap 还是 TreeMap 影响 sum 结果吗?
不影响。无论底层是 HashMap、TreeMap 还是 LinkedHashMap,values() 返回的是无序集合(Collection),stream() 遍历顺序由具体实现决定,但求和是交换律操作,结果恒等。
-
HashMap.values()无序,TreeMap.values()按 key 排序,但 sum 不依赖顺序 - 唯一影响是并发场景:若遍历时
Map被其他线程修改,可能抛ConcurrentModificationException - 高并发下建议用
ConcurrentHashMap,它的values()视图支持弱一致性遍历,不会因修改而中断
性能敏感时别盲目用 stream:原始 for 循环更快
对小规模 Map(几百条以内),stream 和传统循环差异不大;但高频调用或大数据量时,stream 的对象创建、函数式接口调用开销明显。
立即学习“Java免费学习笔记(深入)”;
- 等效的传统写法:
int sum = 0; for (Integer v : map.values()) { if (v != null) sum += v; } -
stream在 JVM 上需触发懒加载、装箱/拆箱、中间操作链构建,JIT 优化有限 - Android 或嵌入式环境更建议手动循环,避免 Dalvik/ART 对
Stream支持不全导致运行时异常 - 如果已用
stream做复杂处理(比如 filter + map + sum 组合),那没问题;但纯求和就单拎出来,别为“函数式”硬套
实际项目里,null 安全和可读性往往比理论性能更重要,但得知道那个临界点在哪——不是所有 Map 都适合流式求和。









