我有一个json
字符串,如下所示,我想将其拆分/分解为多个json
字符串。
输入:
{
"name": "paddy",
"age": 29,
"cities": [
{
"cityName": "Chennai",
"year": "2013-2015"
},
{
"cityName": "Bangalore",
"year": "2015-2019"
}
]
}
我想转换成两个Json字符串
json 1
{
"name": "paddy",
"age": 29,
"cities": [
{
"cityName": "Chennai",
"year": "2013-2015"
}
]
}
json 2
{
"name": "paddy",
"age": 29,
"cities": [
{
"cityName": "Bangalore",
"year": "2015-2019"
}
]
}
到目前为止,我下面的方法是使用杰克逊库。
package com.test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class JsonParser {
public static void main(String[] args) throws IOException {
String json =
"{\n"
+ "\t\"name\": \"paddy\",\n"
+ "\t\"age\": 29,\n"
+ "\t\"cities\": [\n"
+ "\t\t{\n"
+ "\t\t\t\"cityName\": \"Chennai\",\n"
+ "\t\t\t\"year\": \"2013-2015\"\n"
+ "\t\t},\n"
+ "\t\t{\n"
+ "\t\t\t\"cityName\": \"Bangalore\",\n"
+ "\t\t\t\"year\": \"2015-2019\"\n"
+ "\t\t}\n"
+ "\t]\n"
+ "}";
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// Create a list to store the result (the list will store Jackson tree model objects)
List<JsonNode> result = new ArrayList<>();
JsonNode tree = mapper.readTree(json);
JsonNode paths = tree.get("cities");
Iterator<JsonNode> elements = paths.elements();
while (elements.hasNext()) {
JsonNode path = elements.next();
// Create a copy of the tree
JsonNode copyOfTree = mapper.valueToTree(tree);
((ArrayNode)copyOfTree.get("cities")).removeAll().add(path);
// Add the modified tree to the result list
result.add(copyOfTree);
}
// Print the result
for (JsonNode node : result) {
System.out.println(mapper.writeValueAsString(node));
System.out.println();
}
}
}
如果json
较小,则上述方法可以正常工作。有没有更好的方法来处理大型json
文件。例如,假设“城市”有百万个对象。
谢谢。
答案 0 :(得分:1)
您需要考虑许多不同的因素。首先,不要复制整个根对象。如果您有一个大的cities
数组,那么您只会浪费内存来创建新副本并从中删除所有元素。参见以下示例:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.File;
import java.io.IOException;
public class JsonApp {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./spring-basics/src/main/resources/test.json");
ObjectMapper mapper = new ObjectMapper();
// read whole JSON
ObjectNode root = (ObjectNode) mapper.readTree(jsonFile);
String citiesFieldName = "cities";
// remove cities from root, now it contains only common properties
ArrayNode cities = (ArrayNode) root.remove(citiesFieldName);
cities.elements().forEachRemaining(item -> {
// copy root
ObjectNode copyOfRoot = root.deepCopy();
// add one city to copy
copyOfRoot.set(citiesFieldName, copyOfRoot.arrayNode().add(item));
// add to result or send further
System.out.println(copyOfRoot);
});
}
}
以上代码复制root
并将一个元素添加到cities
数组中。现在,我们需要考虑如何处理结果。您可以立即将其发送以进行下一步处理,也可以存储在列表中,然后以批量操作发送。另一个改进可以是将cities
数组拆分为更大的块(超过1个元素)。请参阅this article,了解如何拆分列表。例如,如果您有1_000_000
个元素,请在1_000
个元素块列表中进行拆分。