在Java中基于Parent_ID将扁平JSON转换为父子层级结构
扁平JSON转嵌套父子层级结构的实现方案
我有一个扁平结构的JSON,其中根元素没有Parent_ID,每个父节点可以包含多层嵌套的子节点。需要将其转换为如下的嵌套父子JSON结构:
{ "root":{ "name": "world", "children":[ { "name": "Asia", "children":[ { "name": "India", "children":[ { "name": "WB", "...//multiple nested children can be present" } ] }, { "name": "Pakistan", "children":[ "...//multiple nested children can be present" ] } ] }, { "name": "Europe", "children":[ { "name": "Italy", "children":[ { "name":"... ...//multiple nested children can be present" } ] }, "...//multiple nested children can be present" ] } ] } }
我自己写了一段Java代码,但逻辑有问题,无法实现需求,代码如下:
package jsonflattener; import org.apache.activemq.artemis.utils.json.JSONArray; import org.apache.activemq.artemis.utils.json.JSONException; import org.apache.activemq.artemis.utils.json.JSONObject; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class JSONMapTest { public static void main(String[] args) throws JSONException { JSONArray rootJsonArray = makeJSON(); Map<String, JSONObject> idNameMap = new HashMap<>(); Map<String, Object> idNameMap2 = new HashMap<>(); JSONObject idNameMap3 = new JSONObject(); for (int i = 0; i < rootJsonArray.length(); i++) { JSONObject data = (JSONObject) rootJsonArray.get(i); idNameMap.put(data.getString("id"), data); Set<String> idSet = idNameMap.keySet(); for (String id : idSet) { JSONObject value = idNameMap.get(id); for (Iterator keys = value.keys(); keys.hasNext(); ) { String key = (String) keys.next(); Object pid = value.get("pid"); if (pid.equals("")) { idNameMap2.put("root", value.get("name")); } else if (pid.toString().equals(value.getString(id))) { //Insert in this point System.out.println(pid + ":" + key); } } Object pid = value.get("pid"); } } System.out.println(idNameMap2); } }
我尝试通过ID-名称映射表匹配父ID与键来构建结构,但不清楚如何正确插入节点,需要指导如何用递归或非递归方式实现所需层级结构。
解决方案
核心思路
- 建立节点映射:先把所有扁平节点存入以
id为键的Map,同时为每个节点创建包含name和空children数组的结构,方便后续组装。 - 关联父子节点:遍历每个节点,根据
pid找到对应的父节点,将当前节点加入父节点的children数组。 - 构建根结构:找到
pid为空的根节点,将其包装成最终的root结构。
非递归实现代码
package jsonflattener; import org.apache.activemq.artemis.utils.json.JSONArray; import org.apache.activemq.artemis.utils.json.JSONException; import org.apache.activemq.artemis.utils.json.JSONObject; import java.util.HashMap; import java.util.Map; public class JSONHierarchyConverter { public static void main(String[] args) throws JSONException { JSONArray flatJsonArray = makeJSON(); // 替换为你的扁平JSON数组获取逻辑 // 1. 建立id到带children的节点映射 Map<String, JSONObject> nodeMap = new HashMap<>(); JSONObject rootNode = null; for (int i = 0; i < flatJsonArray.length(); i++) { JSONObject flatNode = flatJsonArray.getJSONObject(i); String id = flatNode.getString("id"); String pid = flatNode.optString("pid", ""); String name = flatNode.getString("name"); // 创建带children的节点结构 JSONObject hierarchicalNode = new JSONObject(); hierarchicalNode.put("name", name); hierarchicalNode.put("children", new JSONArray()); nodeMap.put(id, hierarchicalNode); // 记录根节点(pid为空) if (pid.isEmpty()) { rootNode = hierarchicalNode; } } // 2. 关联父子节点 for (int i = 0; i < flatJsonArray.length(); i++) { JSONObject flatNode = flatJsonArray.getJSONObject(i); String id = flatNode.getString("id"); String pid = flatNode.optString("pid", ""); if (!pid.isEmpty()) { JSONObject parentNode = nodeMap.get(pid); if (parentNode != null) { parentNode.getJSONArray("children").put(nodeMap.get(id)); } } } // 3. 构建最终的root结构 JSONObject result = new JSONObject(); result.put("root", rootNode); System.out.println(result.toString(2)); // 格式化输出 } // 模拟获取扁平JSON数组的方法,实际场景替换为从文件/接口读取 private static JSONArray makeJSON() throws JSONException { JSONArray array = new JSONArray(); // 示例数据,对应你的扁平结构 array.put(new JSONObject().put("id", "1").put("pid", "").put("name", "world")); array.put(new JSONObject().put("id", "2").put("pid", "1").put("name", "Asia")); array.put(new JSONObject().put("id", "3").put("pid", "1").put("name", "Europe")); array.put(new JSONObject().put("id", "4").put("pid", "2").put("name", "India")); array.put(new JSONObject().put("id", "5").put("pid", "2").put("name", "Pakistan")); array.put(new JSONObject().put("id", "6").put("pid", "4").put("name", "WB")); array.put(new JSONObject().put("id", "7").put("pid", "3").put("name", "Italy")); return array; } }
递归实现代码(用于构建子节点)
如果需要用递归方式遍历并构建子节点,可以在上述基础上添加递归方法:
// 递归构建子节点的辅助方法 private static void buildChildren(JSONObject currentNode, Map<String, JSONObject> nodeMap, JSONArray flatArray) throws JSONException { JSONArray children = new JSONArray(); for (int i = 0; i < flatArray.length(); i++) { JSONObject flatNode = flatArray.getJSONObject(i); if (flatNode.getString("pid").equals(currentNode.getString("id"))) { JSONObject childNode = nodeMap.get(flatNode.getString("id")); buildChildren(childNode, nodeMap, flatArray); children.put(childNode); } } currentNode.put("children", children); }
使用时,在建立节点映射后,调用buildChildren(rootNode, nodeMap, flatJsonArray);即可完成递归构建。
内容的提问来源于stack exchange,提问作者micro
相关产品推荐
相关产品推荐

