Java 将具有重复键的 JSON 对象转换为 JSON 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24416960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert JSON object with duplicate keys to JSON array
提问by adamF
I have a JSON string that I get from a database which contains repeated keys. I want to remove the repeated keys by combining their values into an array.
我有一个从包含重复键的数据库中获取的 JSON 字符串。我想通过将它们的值组合到一个数组中来删除重复的键。
For example
例如
Input
输入
{
"a":"b",
"c":"d",
"c":"e",
"f":"g"
}
Output
输出
{
"a":"b",
"c":["d","e"],
"f":"g"
}
The actual data is a large file that may be nested. I will not know ahead of time what or how many pairs there are.
实际数据是一个可能嵌套的大文件。我不会提前知道有什么或多少对。
I need to use Java for this. org.json throws an exception because of the repeated keys, gson can parse the string but each repeated key overwrites the last one. I need to keep all the data.
我需要为此使用Java。org.json 因为key 重复而抛出异常,gson 可以解析字符串但是每个重复的key 都会覆盖最后一个。我需要保留所有数据。
If possible, I'd like to do this without editing any library code
如果可能,我想在不编辑任何库代码的情况下执行此操作
采纳答案by Kainix
As of today the org.json
library version 20170516
provides accumulate()
method that stores the duplicate key entries into JSONArray
截至今天,org.json
库版本20170516
提供accumulate()
了将重复的键条目存储到JSONArray
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("a", "b");
jsonObject.accumulate("c", "d");
jsonObject.accumulate("c", "e");
jsonObject.accumulate("f", "g");
System.out.println(jsonObject);
Output:
输出:
{
"a":"b",
"c":["d","e"],
"f":"g"
}
回答by Mike Elofson
In order to accomplish what you want, you need to create some sort of custom class since JSON
cannot technically have 2 values at one key. Below is an example:
为了完成你想要的,你需要创建某种自定义类,因为JSON
技术上不能一个键有 2 个值。下面是一个例子:
public class SomeClass {
Map<String, List<Object>> values = new HashMap<String, List<Object>>();
public void add(String key, Object o) {
List<Object> value = new ArrayList<Object>();
if (values.containsKey(key)) {
value = values.get(key);
}
value.add(o);
values.put(key, value);
}
public JSONObject toJson() throws JSONException {
JSONObject json = new JSONObject();
JSONArray tempArray = null;
for (Entry<String, List<Object>> en : values.entrySet()) {
tempArray = new JSONArray();
for (Object o : en.getValue()) {
tempArray.add(o);
}
json.put(en.getKey(), tempArray);
}
return json;
}
}
You can then retrieve the values from the database, call the .add(String key, Object o)
function with the column name from the database, and the value (as the Object
param). Then call .toJson()
when you are finished.
然后,您可以从数据库中检索值,使用数据库中.add(String key, Object o)
的列名和值(作为Object
参数)调用函数。然后.toJson()
完成后打电话。
回答by Braj
I want to remove the repeated keys by combining their values into an array.
我想通过将它们的值组合到一个数组中来删除重复的键。
Think other than JSON parsing library. It's very simple Java Program using String.split()
method that convert Json String into Map<String, List<String>>
without using any library.
考虑 JSON 解析库以外的内容。这是非常简单的 Java 程序,使用String.split()
方法将 Json 字符串转换为Map<String, List<String>>
不使用任何库的方法。
Sample code:
示例代码:
String jsonString = ...
// remove enclosing braces and double quotes
jsonString = jsonString.substring(2, jsonString.length() - 2);
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String values : jsonString.split("\",\"")) {
String[] keyValue = values.split("\":\"");
String key = keyValue[0];
String value = keyValue[1];
if (!map.containsKey(key)) {
map.put(key, new ArrayList<String>());
}
map.get(key).add(value);
}
output:
输出:
{
"f": ["g"],
"c": ["d","e"],
"a": ["b"]
}
回答by adamF
Thanks to Mike Elofson and Braj for helping me in the right direction. I only wanted to have the keys with multiple values become arrays so I had to modify the code a bit. Eventually I want it to work for nested JSON as well, as it currently assumes it is flat. However, the following code works for what I need it for at the moment.
感谢 Mike Elofson 和 Braj 在正确的方向上帮助我。我只想让具有多个值的键成为数组,所以我不得不稍微修改一下代码。最终我希望它也适用于嵌套的 JSON,因为它目前假定它是扁平的。但是,以下代码适用于我目前需要的内容。
public static String repeatedKeysToArrays(String jsonIn) throws JSONException
{
//This assumes that the json is flat
String jsonString = jsonIn.substring(2, jsonIn.length() - 2);
JSONObject obj = new JSONObject();
for (String values : jsonString.split("\",\"")) {
String[] keyValue = values.split("\":\"");
String key = keyValue[0];
String value = "";
if (keyValue.length>1) value = keyValue[1];
if (!obj.has(key)) {
obj.put(key, value);
} else {
Object Oold = obj.get(key);
ArrayList<String> newlist = new ArrayList<String>();
//Try to cast as JSONArray. Otherwise, assume it is a String
if (Oold.getClass().equals(JSONArray.class)) {
JSONArray old = (JSONArray)Oold;
//Build replacement value
for (int i=0; i<old.length(); i++) {
newlist.add( old.getString(i) );
}
}
else if (Oold.getClass().equals(String.class)) newlist = new ArrayList<String>(Arrays.asList(new String[] {(String)Oold}));
newlist.add(value);
JSONArray newarr = new JSONArray( newlist );
obj.put(key,newarr);
}
}
return obj.toString();
}