Java中过滤Map的null值应创建新Map而非修改原Map,推荐Stream流式过滤(JDK8+)、手动遍历(低版本兼容)或Guava工具类;需注意判空、字符串空白、自定义对象逻辑空及并发安全。

Java中过滤Map里的null值,核心是创建一个新Map,只保留value不为null的键值对。直接修改原Map可能引发并发问题或结构异常,推荐用不可变或新建方式处理。
使用Java 8 Stream流式过滤
适合JDK 8及以上,代码简洁、可读性强,适用于大多数场景:
- 对entrySet()流式处理,用filter筛选value != null的条目
- 用Collectors.toMap()重建Map,注意处理key重复(一般不会)和null key(需额外判断)
- 示例:
.filter(e -> e.getValue() != null)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
手动遍历+条件put(兼容低版本JDK)
适用于JDK 7或需精细控制逻辑(如同时过滤null key/value、日志记录等):
- 新建HashMap或LinkedHashMap(保持插入顺序)
- 遍历原Map.entrySet(),逐个判断value是否为null,非null才put
- 若还需排除null key,加e.getKey() != null条件
使用Guava工具类(第三方依赖)
如果项目已引入Guava,可用ImmutableMap或Maps.filterEntries:
立即学习“Java免费学习笔记(深入)”;
- Maps.filterEntries(map, entry -> entry.getValue() != null) 返回视图(注意:不是新Map,原Map变更会影响它)
- 如需不可变副本,再套一层ImmutableMap.copyOf()
- 优势是语义清晰、线程安全视图,但增加依赖
注意事项与避坑点
实际清洗时容易忽略的细节:
- Map本身为null?先判空,避免NPE
- value是字符串时,"null"(字符串字面量)≠ null,需额外trim()+isEmpty()判断是否为空白
- 自定义对象作value,注意重写equals/hashCode,否则Stream过滤正常,但业务上可能仍需“逻辑空”判断(如status==null || status.isEmpty())
- 并发Map(如ConcurrentHashMap)建议用computeIfPresent等原子方法,而非先查后删
基本上就这些。选哪种方式,看JDK版本、是否允许依赖、是否需要不可变结果以及是否要兼顾key校验——不复杂但容易忽略边界。










