我有一个JSON
和一些key-value
对。我需要按名称选择并以不同的方式处理其价值。该过程的顺序应与JSON
中列出的键的顺序相同(JSON
是未知的,仅知道它将具有一些键和对应的值,因此无法知道{之外的顺序{1}}。
简化的示例用法:
JSON
问题是String jsonData = "{key1:{some other data}, key2:{sub-key:sub-value}}";
val jsonObject = JSONObject(jsonData)
val names = jsonObject.keys()
if (names.hasNext()) {
val key = names.next()
val valueJson = jsonData.optString(key)
val gson = Gson()
val resultList = ArrayList<Data> () // result should keep the order as the keys in the json
if (key == "key1") {
val parsedResult = gson.fromJson <POJO_1> (valueJson, POJO_1::class.java)
resultList.add(processDataFromKey1(parsedResult))
} else if (key == "key2") {
val parsedResult = gson.fromJson <POJO_2> (valueJson, POJO_2::class.java)
resultList.add(processDataFromKey2(parsedResult))
}
}
键的顺序是jsonObject.keys()
。
那么如何保留undefined
字符串中键的顺序(不想添加依赖项JSON
)
答案 0 :(得分:1)
您可以使用jsonparser而不是jsonreader来控制事件流。 参见https://docs.oracle.com/javaee/7/api/javax/json/stream/JsonParser.html
请注意,您的问题既不是Kotlin也不是gson。
答案 1 :(得分:1)
org.json.JSONObject
在内部使用HashMap
。他们甚至在其中添加了一些评论:
HashMap
专门用于确保元素不被 规范。JSON
通常是一种可移植的传输格式, 允许容器实现为 基于关联访问的更快元素检索。因此, 实施不得依赖于项目的顺序。
使用Gson
。它对com.google.gson.internal.LinkedTreeMap
使用Map
实现。从它的文档中:
可比较键到值的映射。与
TreeMap
不同,此类 将插入顺序用于迭代顺序。仅比较顺序 用于优化有效插入和删除操作。
此实现源自Android 4.1的TreeMap类。
因此,对于JSON
以下的payload
:
{
"status": "status",
"date": "01/10/2019",
"abc": {
"Field1": "value1",
"key": "value2"
},
"rgj": {
"key": "value2",
"Field1": "value3"
},
"name": "Rick"
}
此示例应用程序:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.Map;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder().create();
Type type = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> map = gson.fromJson(new FileReader(jsonFile), type);
map.forEach((k, v) -> {
if (v instanceof Map) {
System.out.println(k);
((Map) v).forEach((k1, v1) -> System.out.println(" " + k1 + " => " + v1));
} else {
System.out.println(k + " => " + v);
}
});
}
}
打印:
status => status
date => 01/10/2019
abc
Field1 => value1
key => value2
rgj
key => value2
Field1 => value3
name => Rick
请注意,key
和Field1
对象中的abc
和rgj
的顺序不同。
答案 2 :(得分:0)
您可以做的另一件事是在示例中引用String jsonData并重建顺序。
类似的东西:
JSONObject json = new JSONObject(jsonData);
Iterator<String> keys = json.keys();
List<KeyOrder> ordering = new ArrayList();
while(keys.hasNext()) {
String key = keys.next();
int loc = jsonData.indexOf('"' + key + '"');
ordering.add(new KeyOrder(loc, key));
}
Collections.sort(ordering);
for(KeyOrder order: ordering) {
Object value = json.get(order.getKey());
// process the key and value
}
public class KeyOrder implements Comparable<KeyOrder> {
private int order;
private String key;
public KeyOrder(int order, String key) {
this.order = order;
this.key = key;
}
@Override
public int compareTo(KeyOrder o) {
return order - o.getOrder();
}
private int getOrder() {
return order;
}
public String getKey() {
return key;
}
}