在Java开发中,Map是常用的数据结构之一,实际业务里经常会遇到Map中存在null值的情况,这些null值可能会在后续的数据处理、序列化、接口返回等环节引发异常,因此需要对Map进行清洗,过滤掉其中的null值。

基础循环遍历过滤方式
最传统的过滤方式是遍历Map的entrySet,判断value是否为null,将非null的键值对放入新的Map中。这种方式兼容性好,适用于所有Java版本。
import java.util.HashMap;
import java.util.Map;
public class MapNullFilterDemo {
public static void main(String[] args) {
// 初始化包含null值的Map
Map<String, Object> originalMap = new HashMap<>();
originalMap.put("name", "张三");
originalMap.put("age", null);
originalMap.put("score", 90);
originalMap.put("address", null);
// 创建新Map存储过滤后的结果
Map<String, Object> filteredMap = new HashMap<>();
// 遍历原Map的entrySet
for (Map.Entry<String, Object> entry : originalMap.entrySet()) {
// 判断value不为null时放入新Map
if (entry.getValue() != null) {
filteredMap.put(entry.getKey(), entry.getValue());
}
}
System.out.println("过滤前的Map:" + originalMap);
System.out.println("过滤后的Map:" + filteredMap);
}
}
使用Java 8 Stream流过滤
Java 8及以上版本可以使用Stream流的方式简化过滤逻辑,代码更简洁,可读性更强。
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class MapStreamFilterDemo {
public static void main(String[] args) {
Map<String, Object> originalMap = new HashMap<>();
originalMap.put("name", "李四");
originalMap.put("age", null);
originalMap.put("score", 85);
originalMap.put("address", null);
// 使用Stream过滤value不为null的entry
Map<String, Object> filteredMap = originalMap.entrySet()
.stream()
// 过滤条件:value不为null
.filter(entry -> entry.getValue() != null)
// 收集到新的Map中
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue
));
System.out.println("过滤前的Map:" + originalMap);
System.out.println("过滤后的Map:" + filteredMap);
}
}
使用Apache Commons Lang工具类过滤
如果项目中已经引入了Apache Commons Lang依赖,可以使用MapUtils相关的方法简化操作,减少重复代码。
import org.apache.commons.lang3.MapUtils;
import java.util.HashMap;
import java.util.Map;
public class MapCommonsFilterDemo {
public static void main(String[] args) {
Map<String, Object> originalMap = new HashMap<>();
originalMap.put("name", "王五");
originalMap.put("age", null);
originalMap.put("score", 88);
originalMap.put("address", null);
// 使用MapUtils的predicate方法过滤null值
Map<String, Object> filteredMap = MapUtils.filterEntries(originalMap,
entry -> entry.getValue() != null
);
System.out.println("过滤前的Map:" + originalMap);
System.out.println("过滤后的Map:" + filteredMap);
}
}
不同过滤策略的对比
不同的过滤方式有不同的适用场景,下面是几种方式的对比:
| 过滤方式 | 适用Java版本 | 代码简洁度 | 性能表现 | 适用场景 |
|---|---|---|---|---|
| 基础循环遍历 | 所有版本 | 一般 | 较好 | 低版本Java项目,或者需要兼容旧环境的场景 |
| Stream流过滤 | Java 8及以上 | 高 | 略低于循环遍历 | Java 8以上项目,追求代码简洁的场景 |
| 第三方工具类过滤 | 所有版本(需引入依赖) | 高 | 依赖工具类实现 | 项目已经引入对应工具库,减少自定义代码的场景 |
注意事项
- 以上过滤方式都会生成新的Map,不会修改原有的Map对象,如果需要修改原Map,需要先清空原Map再重新放入过滤后的数据,或者使用迭代器遍历删除。
- 如果Map的key也可能为null,需要额外增加key的非null判断,避免后续逻辑出现问题。
- Stream流过滤时如果原Map为空,不会抛出异常,会返回空的Map,无需额外做空判断。
实际开发中可以根据项目的Java版本、依赖情况以及具体的业务需求选择最合适的Map null值过滤方式,保证代码的健壮性和可读性。