Java实现嵌套JSON合并:基于相同ID节点合并子节点
解决方案
你需要的是递归合并层级JSON节点,按id去重并合并子节点,Java里可以用Jackson库轻松实现,下面是具体步骤和代码:
1. 定义实体类(映射JSON结构)
先把JSON的层级结构映射为Java对象,方便后续操作:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @JsonIgnoreProperties(ignoreUnknown = true) public class Node { private String id; private List<Node> children = new ArrayList<>(); // 构造器、Getter、Setter public Node() {} public Node(String id) { this.id = id; } public String getId() { return id; } public void setId(String id) { this.id = id; } public List<Node> getChildren() { return children; } public void setChildren(List<Node> children) { this.children = children; } } @JsonIgnoreProperties(ignoreUnknown = true) public class JsonRoot { private List<Node> nodes; public List<Node> getNodes() { return nodes; } public void setNodes(List<Node> nodes) { this.nodes = nodes; } }
2. 编写递归合并工具方法
核心逻辑是:将所有节点按id分组,相同id的节点合并子节点,递归处理多层级结构:
public class NodeMerger { // 合并多组节点列表 public static List<Node> mergeNodes(List<Node>... nodeLists) { List<Node> allNodes = new ArrayList<>(); for (List<Node> list : nodeLists) { if (list != null) allNodes.addAll(list); } // 按id分组,合并每组内的节点 return allNodes.stream() .collect(Collectors.groupingBy(Node::getId)) .values() .stream() .map(NodeMerger::mergeSameIdNodes) .collect(Collectors.toList()); } // 合并同一id的多个节点,重点递归合并子节点 private static Node mergeSameIdNodes(List<Node> nodesWithSameId) { if (nodesWithSameId.isEmpty()) return null; Node mergedNode = new Node(nodesWithSameId.get(0).getId()); List<Node> allChildren = new ArrayList<>(); for (Node node : nodesWithSameId) { allChildren.addAll(node.getChildren()); } mergedNode.setChildren(mergeNodes(allChildren)); return mergedNode; } }
3. 完整示例(解析JSON + 合并 + 序列化)
import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class JsonMergeDemo { public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(); // 第一个JSON字符串 String json1 = """ { "nodes": [ { "id": "Main", "children": [ { "id": "C1", "children": [ { "id": "C1.1", "children": [] } ] } ] } ] }"""; // 第二个JSON字符串 String json2 = """ { "nodes": [ { "id": "Main", "children": [ { "id": "C2", "children": [ { "id": "C2.1", "children": [] } ] }, { "id": "C3", "children": [ { "id": "C3.1", "children": [] } ] } ] } ] }"""; // 解析JSON到实体类 JsonRoot root1 = mapper.readValue(json1, JsonRoot.class); JsonRoot root2 = mapper.readValue(json2, JsonRoot.class); // 合并节点 List<Node> mergedNodes = NodeMerger.mergeNodes(root1.getNodes(), root2.getNodes()); // 封装回根对象并序列化为格式化后的JSON JsonRoot mergedRoot = new JsonRoot(); mergedRoot.setNodes(mergedNodes); String mergedJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mergedRoot); // 输出结果 System.out.println(mergedJson); } }
4. Maven依赖配置
需要添加Jackson核心依赖:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> <!-- 使用最新稳定版本即可 --> </dependency>
备选方案:直接操作JSON节点(无需实体类)
如果不想定义实体类,也可以直接用Jackson的JsonNode递归处理:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class JsonNodeMerger { public static JsonNode mergeJsonNodes(JsonNode... nodes) { ObjectMapper mapper = new ObjectMapper(); ObjectNode mergedRoot = mapper.createObjectNode(); ArrayNode mergedNodes = mapper.createArrayNode(); Map<String, JsonNode> nodeMap = new HashMap<>(); for (JsonNode root : nodes) { JsonNode nodesArray = root.get("nodes"); if (nodesArray != null && nodesArray.isArray()) { Iterator<JsonNode> iterator = nodesArray.elements(); while (iterator.hasNext()) { JsonNode node = iterator.next(); String id = node.get("id").asText(); nodeMap.put(id, nodeMap.containsKey(id) ? mergeSingleNode(nodeMap.get(id), node) : node); } } } mergedNodes.addAll(nodeMap.values()); mergedRoot.set("nodes", mergedNodes); return mergedRoot; } private static JsonNode mergeSingleNode(JsonNode existing, JsonNode newNode) { ObjectMapper mapper = new ObjectMapper(); ObjectNode merged = mapper.createObjectNode(); merged.put("id", existing.get("id").asText()); ArrayNode mergedChildren = mapper.createArrayNode(); Map<String, JsonNode> childMap = new HashMap<>(); addChildrenToMap(childMap, existing.get("children")); addChildrenToMap(childMap, newNode.get("children")); childMap.values().forEach(mergedChildren::add); merged.set("children", mergedChildren); return merged; } private static void addChildrenToMap(Map<String, JsonNode> map, JsonNode childrenArray) { if (childrenArray == null || !childrenArray.isArray()) return; Iterator<JsonNode> iterator = childrenArray.elements(); while (iterator.hasNext()) { JsonNode child = iterator.next(); String id = child.get("id").asText(); map.put(id, map.containsKey(id) ? mergeSingleNode(map.get(id), child) : child); } } }
调用方式示例:
JsonNode merged = JsonNodeMerger.mergeJsonNodes(mapper.readTree(json1), mapper.readTree(json2)); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(merged));
内容的提问来源于stack exchange,提问作者PowerfullDeveloper
相关产品推荐
相关产品推荐

