如何递归移除任意深度LinkedTreeMap中的嵌套null值
问题原因
你原有代码存在3个核心问题导致无法处理任意深度的嵌套JSON:
- 增强for循环遍历
LinkedTreeMap的entrySet时直接调用remove删除元素,会触发ConcurrentModificationException并发修改异常,Java不允许在增强for遍历集合的过程中直接修改集合长度 - 未适配JSON数组对应的
List类型,你的示例JSON中就包含attributes、modelGroup这类数组结构,数组内嵌套的对象也需要递归处理 - 你疑惑的递归返回值问题不需要额外处理,Java是引用传递,递归调用时传入的子
LinkedTreeMap是引用对象,修改直接作用在原对象上,不需要重新赋值到父Map
修正后的实现代码
import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.internal.LinkedTreeMap; import java.util.*; public class JsonNullCleaner { private static final Gson gson = new Gson(); public static LinkedTreeMap removeNullJsonObjects(Object object) { JsonElement jsonElement = gson.toJsonTree(object); LinkedTreeMap<Object, Object> linkedTreeMap = gson.fromJson(jsonElement, LinkedTreeMap.class); cleanNullRecursive(linkedTreeMap); return linkedTreeMap; } /** * 递归清理任意嵌套层级的null值 */ private static void cleanNullRecursive(Object obj) { // 处理JSON对象对应LinkedTreeMap类型 if (obj instanceof LinkedTreeMap<?, ?> map) { Iterator<? extends Map.Entry<?, ?>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<?, ?> entry = iterator.next(); Object value = entry.getValue(); if (value == null) { // 迭代器安全删除null值对应的键 iterator.remove(); } else { // 递归处理当前值 cleanNullRecursive(value); // 可选扩展:如果需要同时清理无属性的空对象、空数组,放开下方注释即可 // if ((value instanceof LinkedTreeMap<?,?> && ((LinkedTreeMap<?,?>) value).isEmpty()) // || (value instanceof List<?> && ((List<?>) value).isEmpty())) { // iterator.remove(); // } } } } // 处理JSON数组对应List类型 else if (obj instanceof List<?> list) { for (Object item : list) { cleanNullRecursive(item); } } // 基本类型、字符串等原子类型无需额外处理 } }
实现说明
该实现可以处理任意深度的JSON嵌套结构,支持JSON对象、JSON数组的递归遍历,所有层级的null值都会被清理。可选扩展逻辑可以根据你的业务需求选择是否开启,开启后会自动删除没有任何有效属性的空对象、空数组。
内容的提问来源于stack exchange,提问作者Janusz Januszewski
相关产品推荐
相关产品推荐

