我有一个带有对象列表的JSON,列表中的任何项目都可以具有null或与键值相同的对象。我正在寻找一种更快的方法来解析json以得出我的最终结果。 数据结构看起来像 -
[
{
"firstName": "Bruce",
"familyMembers": null
},
{
"firstName": "Gates Family",
"familyMembers": [
{
"firstName": "Bill",
"familyMembers": null
},
{
"firstName": "Steve",
"familyMembers": null
}
]
},
{
"firstName": "Lee",
"familyMembers": null
},
{
"firstName": "Chan",
"familyMembers": null
}
]
输出应该是一个set =(" Bruce"," Bill"," Steve"," Lee",&#34 ;陈"。)
我正在寻找一种在Java中做到这一点的最好方法,这样我就不会因为陷入这个解析地狱而增加我的响应时间。 感谢你的时间。
答案 0 :(得分:1)
尝试我的递归实现。
public static void jsonArrayToSet(JSONArray jAry, Set<String> result, String targetKey, String subArrayKey, boolean includeNode){
try {
for (int i = 0; i < jAry.length(); i++) {
JSONObject jObj = jAry.getJSONObject(i);
boolean hasSubArray = false;
JSONArray subArray = null;
if(jObj.has(subArrayKey)){
Object possibleSubArray = jObj.get(subArrayKey);
if(possibleSubArray instanceof JSONArray){
hasSubArray = true;
subArray = (JSONArray) possibleSubArray;
}
}
if(hasSubArray){
if(includeNode){
result.add(jObj.getString(targetKey));
}
jsonArrayToSet(subArray, result, targetKey, subArrayKey, includeNode);
} else {
result.add(jObj.getString(targetKey));
}
}
} catch (JSONException e){
e.printStackTrace();
}
}
jAry
:来源JSONArray
。
result
:您要写的Set
。
targetKey
:映射到您要添加到result
的条目的键。
subArrayKey
:映射到子JSONArray
的键。
includeNode
:当前JSONOnject
是包含子数组的节点时,请将其添加到result
。
在您的情况下,您可以致电:
jsonArrayToSet(yourJsonArray, yourSet, "firstName", "familyMembers", false);
答案 1 :(得分:1)
正如我的评论所述。
您的第一个问题是JSON文件中的内容。根据标准,它应该包含一组{}。
实施例
{
"members": [
{
"firstName": "Bruce",
"familyMembers": null
},
{
"firstName": "Gates Family",
"familyMembers": [
{
"firstName": "Bill",
"familyMembers": null
},
{
"firstName": "Steve",
"familyMembers": null
}
]
},
{
"firstName": "Lee",
"familyMembers": null
},
{
"firstName": "Chan",
"familyMembers": null
}
]
}
另外,我认为“盖茨家族”的价值应该是产出的一部分?因为它在“FirstName”属性下。
无论如何,这是我的解决方案,它基于org.json库。它还使用Goggle的GSon库,我用它来读取JSON文件。
import org.json.*;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
public class solution {
public static final String JSON_DATA_FILE_PATH = "./data/source_37848106.json";
private static boolean hasMoreFamilyName(JSONObject json) {
return json.has("familyMembers") && json.get("familyMembers") != JSONObject.NULL;
}
private static void trackFirstName(Map<String, Integer> nameTracker, JSONObject json) {
if (!nameTracker.containsKey(json.getString("firstName"))) {
nameTracker.put(json.getString("firstName"), /*DUMMY VALUE =*/1);
}
}
private static void getNames(Map<String,Integer> nameTracker, JSONArray jsonArr) {
for (int i = 0; i< jsonArr.length(); i++) {
JSONObject item = jsonArr.getJSONObject(i);
if (hasMoreFamilyName(item)) {
getNames(nameTracker, item.getJSONArray("familyMembers"));
}
trackFirstName(nameTracker, item);
}
}
public static void main(String[] args) {
Map<String, Integer> nameTracker = new HashMap<>();
try {
String text = Files.toString(new File(JSON_DATA_FILE_PATH), Charsets.UTF_8);
JSONObject json = new JSONObject(text);
getNames(nameTracker, json.getJSONArray("members"));
}
catch (Exception ex) {
System.out.println("Something is wrong.");
}
for (Map.Entry<String,Integer> entry : nameTracker.entrySet()) {
System.out.println(entry.getKey());
}
}
答案 2 :(得分:0)
您可以使用jackson-databind-2.6.5.jar
中定义的ObjectMapper使用类似于json模式的字段定义一个java类,然后将它们绑定为:
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
Family family=objectMapper.readValue(jsonString, Family.class);
现在您将拥有一个类似于json字符串模式的java对象,您可以按自己喜欢的方式打印它。