从 LinkedHashMap 构建有序 JSON 字符串
Building ordered JSON String from LinkedHashMap
我需要按插入顺序排列 Key/Value 对,所以我选择使用 LinkedHashMap
而不是 HashMap
。但我需要将 LinkedHashMap
转换为 JSON 字符串,其中 LinkedHashMap
中的顺序在字符串中保持不变。
但目前我正在通过以下方式实现它:
- 首先将LinkedHashMap转换为JSON。
然后将JSON转换成字符串。
import java.util.LinkedHashMap;
import java.util.Map;
import org.json.JSONObject;
public class cdf {
public static void main(String[] args) {
Map<String,String > myLinkedHashMap = new LinkedHashMap<String, String>();
myLinkedHashMap.put("1","first");
myLinkedHashMap.put("2","second");
myLinkedHashMap.put("3","third");
JSONObject json = new JSONObject(myLinkedHashMap);
System.out.println(json.toString());
}
}
输出为:
{"3":"third","2":"second","1":"first"} .
但是我想要按插入键的顺序,像这样:
{"1":"first","2":"second","3":"third"}
一旦我将 LinkedHashMap
转换为 JSON 它就失去了它的顺序(很明显 JSON 没有顺序的概念)因此字符串也出来了秩序。现在,如何生成顺序与 LinkedHashMap
?
相同的 JSON 字符串
为有序对创建 JsonArray...
JSONArray orderedJson=new JSONArray();
Iterator iterator= ;
while (iterator.hasNext()) {
Map.Entry me = (Map.Entry)iteratornext();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
JSONObject tmpJson=new JSONObject ();
tmpJson.put(me.getKey(),me.getValue());//add key/value to tmpjson
orderedJson.add(tmpJson);//add tmpjson to orderedJson
}
JSON 由于 linkedhashmap 参数均为字符串,因此未采用插入顺序。像下面提到的代码那样将第一个参数更改为 Integer 是否可以:
Map<Integer,String > myLinkedHashMap = new LinkedHashMap<>();
myLinkedHashMap.put(1,"first");
myLinkedHashMap.put(2,"second");
myLinkedHashMap.put(3,"third");
System.out.println(myLinkedHashMap);
JSONObject json = new JSONObject(myLinkedHashMap);
System.out.println(json.toString());
Gson 如果你是朋友。这会将有序地图打印成有序的 JSON 字符串。
如果要保留插入顺序,请使用 LinkedHashMap
。
我使用的是最新版本的Gson(2.8.5),你可以通过下面的选项下载post。
import java.util.*;
import com.google.gson.Gson;
public class OrderedJson {
public static void main(String[] args) {
// Create a new ordered map.
Map<String,String> myLinkedHashMap = new LinkedHashMap<String, String>();
// Add items, in-order, to the map.
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(myLinkedHashMap, LinkedHashMap.class);
// Print ordered string.
System.out.println(json); // {"1":"first","2":"second","3":"third"}
}
}
如果您希望项目始终插入正确的位置,请改用 TreeMap
。
import java.util.*;
import com.google.gson.Gson;
public class OrderedJson {
public static void main(String[] args) {
// Create a new ordered map.
Map<String,String> myTreeHashMap = new TreeMap<String, String>();
// Add items, in any order, to the map.
myTreeHashMap.put("3", "third");
myTreeHashMap.put("1", "first");
myTreeHashMap.put("2", "second");
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(myTreeHashMap, TreeMap.class);
// Print ordered string.
System.out.println(json); // {"1":"first","2":"second","3":"third"}
}
}
依赖选项
行家
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Gradle
compile 'com.google.code.gson:gson:2.8.5'
或者您可以访问 Maven Central 以获取更多下载选项。
要按字母顺序排序,这是 Jackson 2 的正确方法。*:
Map<String, String> myLinkedHashMap = new LinkedHashMap<String, String>();
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
try {
System.out.println(mapper.writeValueAsString(myLinkedHashMap));
//prints {"1":"first","2":"second","3":"third"}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
JSONObject
意味着使用 org.json
库。不要那样做;它是旧原型,有更好的选择,如 Jackson 和 GSON。
使用 Jackson,您只需使用:
String json = new ObjectMapper().writeValueAsString(myLinkedHashMap);
并获取 JSON 字符串,其中包含您的地图使用的任何遍历顺序的条目。
我运行遇到了同样的问题。我不得不使用这个特定的库,第一个元素必须带有键“$type”。
这是我的决定:
import org.json.JSONObject;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
class TypedJSONObject extends JSONObject {
private static final String KEY = "$type";
@Override
public Set<Map.Entry<String, Object>> entrySet() {
Set<Map.Entry<String, Object>> superSet = super.entrySet();
Set<Map.Entry<String, Object>> returnSet = new LinkedHashSet<>();
HashMap<String, Object> map = new HashMap<>();
for (Map.Entry<String, Object> entry : superSet) {
if (entry.getKey().equals(KEY)) {
map.put(KEY, entry.getValue());
break;
}
}
Set<Map.Entry<String, Object>> entries = map.entrySet();
returnSet.addAll(entries);
returnSet.addAll(superSet);
return returnSet;
}
}
如你所见,我重写了方法 entrySet,它在方法 toString
中使用
我创建了一个 hacky 解决方案,不应该用于生产,我只是用它来手动生成 json 文件
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import org.json.JSONObject;
public class SortedJSONObject extends JSONObject {
public SortedJSONObject() {
super();
try {
Field mapField = JSONObject.class.getDeclaredField("map");
mapField.setAccessible(true);
mapField.set(this, new LinkedHashMap());
mapField.setAccessible(false);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
我需要按插入顺序排列 Key/Value 对,所以我选择使用 LinkedHashMap
而不是 HashMap
。但我需要将 LinkedHashMap
转换为 JSON 字符串,其中 LinkedHashMap
中的顺序在字符串中保持不变。
但目前我正在通过以下方式实现它:
- 首先将LinkedHashMap转换为JSON。
然后将JSON转换成字符串。
import java.util.LinkedHashMap; import java.util.Map; import org.json.JSONObject; public class cdf { public static void main(String[] args) { Map<String,String > myLinkedHashMap = new LinkedHashMap<String, String>(); myLinkedHashMap.put("1","first"); myLinkedHashMap.put("2","second"); myLinkedHashMap.put("3","third"); JSONObject json = new JSONObject(myLinkedHashMap); System.out.println(json.toString()); } }
输出为:
{"3":"third","2":"second","1":"first"} .
但是我想要按插入键的顺序,像这样:
{"1":"first","2":"second","3":"third"}
一旦我将 LinkedHashMap
转换为 JSON 它就失去了它的顺序(很明显 JSON 没有顺序的概念)因此字符串也出来了秩序。现在,如何生成顺序与 LinkedHashMap
?
为有序对创建 JsonArray...
JSONArray orderedJson=new JSONArray();
Iterator iterator= ;
while (iterator.hasNext()) {
Map.Entry me = (Map.Entry)iteratornext();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
JSONObject tmpJson=new JSONObject ();
tmpJson.put(me.getKey(),me.getValue());//add key/value to tmpjson
orderedJson.add(tmpJson);//add tmpjson to orderedJson
}
JSON 由于 linkedhashmap 参数均为字符串,因此未采用插入顺序。像下面提到的代码那样将第一个参数更改为 Integer 是否可以:
Map<Integer,String > myLinkedHashMap = new LinkedHashMap<>();
myLinkedHashMap.put(1,"first");
myLinkedHashMap.put(2,"second");
myLinkedHashMap.put(3,"third");
System.out.println(myLinkedHashMap);
JSONObject json = new JSONObject(myLinkedHashMap);
System.out.println(json.toString());
Gson 如果你是朋友。这会将有序地图打印成有序的 JSON 字符串。
如果要保留插入顺序,请使用 LinkedHashMap
。
我使用的是最新版本的Gson(2.8.5),你可以通过下面的选项下载post。
import java.util.*;
import com.google.gson.Gson;
public class OrderedJson {
public static void main(String[] args) {
// Create a new ordered map.
Map<String,String> myLinkedHashMap = new LinkedHashMap<String, String>();
// Add items, in-order, to the map.
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(myLinkedHashMap, LinkedHashMap.class);
// Print ordered string.
System.out.println(json); // {"1":"first","2":"second","3":"third"}
}
}
如果您希望项目始终插入正确的位置,请改用 TreeMap
。
import java.util.*;
import com.google.gson.Gson;
public class OrderedJson {
public static void main(String[] args) {
// Create a new ordered map.
Map<String,String> myTreeHashMap = new TreeMap<String, String>();
// Add items, in any order, to the map.
myTreeHashMap.put("3", "third");
myTreeHashMap.put("1", "first");
myTreeHashMap.put("2", "second");
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(myTreeHashMap, TreeMap.class);
// Print ordered string.
System.out.println(json); // {"1":"first","2":"second","3":"third"}
}
}
依赖选项
行家
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Gradle
compile 'com.google.code.gson:gson:2.8.5'
或者您可以访问 Maven Central 以获取更多下载选项。
要按字母顺序排序,这是 Jackson 2 的正确方法。*:
Map<String, String> myLinkedHashMap = new LinkedHashMap<String, String>();
myLinkedHashMap.put("1", "first");
myLinkedHashMap.put("2", "second");
myLinkedHashMap.put("3", "third");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
try {
System.out.println(mapper.writeValueAsString(myLinkedHashMap));
//prints {"1":"first","2":"second","3":"third"}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
JSONObject
意味着使用 org.json
库。不要那样做;它是旧原型,有更好的选择,如 Jackson 和 GSON。
使用 Jackson,您只需使用:
String json = new ObjectMapper().writeValueAsString(myLinkedHashMap);
并获取 JSON 字符串,其中包含您的地图使用的任何遍历顺序的条目。
我运行遇到了同样的问题。我不得不使用这个特定的库,第一个元素必须带有键“$type”。 这是我的决定:
import org.json.JSONObject;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
class TypedJSONObject extends JSONObject {
private static final String KEY = "$type";
@Override
public Set<Map.Entry<String, Object>> entrySet() {
Set<Map.Entry<String, Object>> superSet = super.entrySet();
Set<Map.Entry<String, Object>> returnSet = new LinkedHashSet<>();
HashMap<String, Object> map = new HashMap<>();
for (Map.Entry<String, Object> entry : superSet) {
if (entry.getKey().equals(KEY)) {
map.put(KEY, entry.getValue());
break;
}
}
Set<Map.Entry<String, Object>> entries = map.entrySet();
returnSet.addAll(entries);
returnSet.addAll(superSet);
return returnSet;
}
}
如你所见,我重写了方法 entrySet,它在方法 toString
中使用我创建了一个 hacky 解决方案,不应该用于生产,我只是用它来手动生成 json 文件
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import org.json.JSONObject;
public class SortedJSONObject extends JSONObject {
public SortedJSONObject() {
super();
try {
Field mapField = JSONObject.class.getDeclaredField("map");
mapField.setAccessible(true);
mapField.set(this, new LinkedHashMap());
mapField.setAccessible(false);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}