如何生成含未扁平化JSON列表的嵌套JSON?求Java解决方案
多级JSON对象嵌套转换解决方案
核心思路
- 构建索引映射:先把输入列表中所有一级对象的键(如
key1、key2)和对应的JSON对象存入HashMap,后续可快速通过键查找对应对象。 - 递归替换引用:遍历每个JSON对象的所有值,若值为非空字符串且能在索引映射中找到对应键,则用该键对应的JSON对象替换这个字符串,继续递归处理替换后的对象,直到所有可替换的引用都处理完成。
- 收集顶级对象:最终收集那些未被任何其他对象引用的顶级对象(即该对象的键没有出现在其他对象的值中),组成输出列表。
Java 实现示例(基于Jackson库)
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.*; public class JsonNester { private static final ObjectMapper mapper = new ObjectMapper(); public static List<JsonNode> nestJsonObjects(List<JsonNode> inputList) throws Exception { // 构建键到JSON对象的映射 Map<String, JsonNode> keyToNodeMap = new HashMap<>(); Set<String> referencedKeys = new HashSet<>(); for (JsonNode node : inputList) { String key = node.fieldNames().next(); JsonNode value = node.get(key); keyToNodeMap.put(key, value); // 收集所有被引用的键 collectReferencedKeys(value, referencedKeys); } // 递归替换所有引用 Map<String, JsonNode> processedNodes = new HashMap<>(); for (Map.Entry<String, JsonNode> entry : keyToNodeMap.entrySet()) { processedNodes.put(entry.getKey(), replaceReferences(entry.getValue(), keyToNodeMap)); } // 收集未被引用的顶级对象 List<JsonNode> result = new ArrayList<>(); for (Map.Entry<String, JsonNode> entry : processedNodes.entrySet()) { if (!referencedKeys.contains(entry.getKey())) { ObjectNode topNode = mapper.createObjectNode(); topNode.set(entry.getKey(), entry.getValue()); result.add(topNode); } } return result; } // 递归收集所有被引用的键 private static void collectReferencedKeys(JsonNode node, Set<String> referencedKeys) { if (node.isObject()) { for (JsonNode value : node.values()) { if (value.isTextual() && !value.asText().isEmpty()) { referencedKeys.add(value.asText()); } else if (value.isObject()) { collectReferencedKeys(value, referencedKeys); } } } } // 递归替换引用 private static JsonNode replaceReferences(JsonNode node, Map<String, JsonNode> keyToNodeMap) { if (node.isObject()) { ObjectNode newNode = mapper.createObjectNode(); for (Iterator<Map.Entry<String, JsonNode>> it = node.fields(); it.hasNext(); ) { Map.Entry<String, JsonNode> entry = it.next(); JsonNode value = entry.getValue(); if (value.isTextual() && !value.asText().isEmpty()) { String refKey = value.asText(); if (keyToNodeMap.containsKey(refKey)) { // 替换为对应的对象,并继续递归处理 newNode.set(entry.getKey(), replaceReferences(keyToNodeMap.get(refKey), keyToNodeMap)); } else { newNode.set(entry.getKey(), value); } } else if (value.isObject()) { newNode.set(entry.getKey(), replaceReferences(value, keyToNodeMap)); } else { newNode.set(entry.getKey(), value); } } return newNode; } return node; } public static void main(String[] args) throws Exception { // 测试用例1输入 String testInput1 = "[{\"key1\": {\"valueA\": \"\", \"valueB\": \"\"}},\n" + "{\"key2\": {\"valueC\": \"key3\"}},\n" + "{\"key3\": {\"valueD\": \"\", \"valueE\": \"\"}}]"; List<JsonNode> input1 = mapper.readValue(testInput1, mapper.getTypeFactory().constructCollectionType(List.class, JsonNode.class)); List<JsonNode> output1 = nestJsonObjects(input1); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(output1)); // 测试用例2输入 String testInput2 = "[{\"key1\": {\"valueA\": \"key2\"}},\n" + "{\"key2\": {\"valueB\": \"key3\"}},\n" + "{\"key3\": {\"valueC\": \"\", \"valueD\": \"\"}}]"; List<JsonNode> input2 = mapper.readValue(testInput2, mapper.getTypeFactory().constructCollectionType(List.class, JsonNode.class)); List<JsonNode> output2 = nestJsonObjects(input2); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(output2)); } }
推荐Java库
- Jackson:Java生态中最常用的JSON处理库,提供灵活的树模型(
JsonNode)和数据绑定功能,非常适合处理这种递归嵌套的JSON结构,上述示例就是基于Jackson实现的。 - Gson:Google出品的JSON库,同样支持树模型(
JsonObject)和递归操作,API简洁易懂,也能轻松实现需求中的转换逻辑。
测试结果验证
- 测试用例1执行后,输出与预期一致:
[{"key1": {"valueA": "", "valueB": ""}}, {"key2": {"valueC": {"valueD": "", "valueE": ""}}}] - 测试用例2执行后,输出与预期一致:
[{"key1": {"valueA": {"valueB": {"valueC": "", "valueD": ""}}}}]
内容的提问来源于stack exchange,提问作者electronyoon
相关产品推荐
相关产品推荐

