
本文介绍一种通用、可扩展的 Java 递归扁平化方案,支持 Map、数组、Iterable 和普通 POJO 对象,能将深层嵌套结构(含列表索引)转换为带路径前缀的扁平化 Map。
本文介绍一种通用、可扩展的 java 递归扁平化方案,支持 map、数组、iterable 和普通 pojo 对象,能将深层嵌套结构(含列表索引)转换为带路径前缀的扁平化 `map
在处理 JSON 数据或配置对象时,常需将嵌套 Java 对象(如 POJO、Map、List)转换为单层键值结构,便于日志记录、规则匹配、数据库存储或前端透传。例如,将含父子关系与列表字段的对象,转换为形如 "parentClass.childClassList[0].stringField" 的扁平键。
以下是一个健壮、生产就绪的递归扁平化工具方法:
private static Map<string object> convertToFlatMap(String prefix, Object obj, Map<string object> map) {
if (obj == null) {
return map;
}
// 处理 Map 类型:递归展开 key-value 对
if (obj instanceof Map) {
Map, ?> objMap = (Map, ?>) obj;
objMap.forEach((key, value) -> {
String fullKey = prefix.isEmpty() ? key.toString() : prefix + "." + key.toString();
convertToFlatMap(fullKey, value, map);
});
return map;
}
// 处理数组:按索引生成路径(如 "list[0]")
if (obj.getClass().isArray()) {
Object[] array = (Object[]) obj;
for (int i = 0; i iterable = (Iterable>) obj;
int i = 0;
for (Object item : iterable) {
String fullKey = prefix + "[" + i + "]";
convertToFlatMap(fullKey, item, map);
i++;
}
return map;
}
// 基础类型(含 String)直接写入
if (obj.getClass().isPrimitive() || obj instanceof String || obj instanceof Number || obj instanceof Boolean || obj instanceof Character) {
map.put(prefix, obj);
return map;
}
// 普通 Java 对象(POJO):通过反射遍历所有声明字段
try {
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true); // 允许访问 private 字段
String fullKey = prefix.isEmpty() ? field.getName() : prefix + "." + field.getName();
Object fieldValue = field.get(obj);
convertToFlatMap(fullKey, fieldValue, map);
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to access field '" + field.getName() + "' in " + obj.getClass().getSimpleName(), e);
}
return map;
}</string></string>
使用方式:
// 假设 yourObject 是对应题干 JSON 结构的 Java 实例(如 Jackson 反序列化后的 Map 或 POJO)
Map<string object> flatMap = convertToFlatMap("", yourObject, new HashMap());
System.out.println(flatMap);
// 输出示例:
// {parentClass.parentField1=parentFieldValue1, parentClass.parentField2=parentFieldValue2,
// parentClass.childClass.childField1=childFieldValue1, ...}</string>
✅ 关键特性说明:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- ✅ 支持任意嵌套深度(Map → POJO → List → Map…)
- ✅ 列表/数组自动编号索引([0], [1]),保留结构位置语义
- ✅ 兼容 Jackson 反序列化的 LinkedHashMap、ArrayList 等标准容器
- ✅ 对 POJO 使用反射,无需注解或接口实现
- ✅ 安全跳过 null 值,避免 NPE
⚠️ 注意事项:
- 反射访问 private 字段需开启 setAccessible(true),在严格安全策略(如某些容器或模块化 JDK)下可能受限;如需更高兼容性,建议搭配 Lombok @Getter + getters 访问,或改用 Jackson 的 ObjectMapper.convertValue() 配合自定义 SimpleModule。
- 循环引用(A → B → A)会导致无限递归 —— 生产环境建议增加 ThreadLocal
> 缓存已访问对象 ID 进行检测。 - Iterable 分支对 Set 等无序集合生成的索引不具备语义稳定性,若需确定性输出,应预转为 List。
该方法轻量、零依赖,可无缝集成至工具类库,是 Java 中实现 JSON 式扁平化的高效实践方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










