public static void main ( String [] args) { LinkedHashMap<Integer, String > map = new LinkedHashMap<>(); map. put ( 1 , "A" ); map. put ( 3 , "A" ); map. put ( 8 , "A" ); map. put ( 5 , "A" ); //原始顺序 System.out. println ( "原始顺序:" ); for (Object o : map. entrySet ()) { System.out. printf ( "%s " , o); //fastjson String fJson = JSON. toJSONString (map); Map m = JSONObject. parseObject (fJson, Map. class ); System.out. println (); System.out. println ( "fastjson:" ); for (Object o : m. entrySet ()) { System.out. printf ( "%s " , o);
原始顺序:
1=A 3=A 8=A 5=A 
fastjson:
1=A 8=A 5=A 3=A 

问题是出在fastjson的JSON.parseObject()方法上,debug代码到如下部分(版本1.1.23):

com.alibaba.fastjson.JSONObject#JSONObject()

    public JSONObject() {
        this(16, false);

com.alibaba.fastjson.JSONObject#JSONObject(int, boolean)

     public JSONObject(int initialCapacity, boolean ordered) {
        if (ordered) {
            this.map = new LinkedHashMap(initialCapacity);
        } else {
            this.map = new AntiCollisionHashMap(initialCapacity);

由于会默认ordered = false 所以会返回一个AntiCollisionHashMap类型对象,然后用该对象去进行put赋值,返回的该map对象无法保证我们想要的顺序。

详见fastjson issue: github.com/alibaba/fas…

方法1: 采用gson将json字符串转换为map

gson实现:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
    public static void main(String[] args) {
        LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
        map.put(1, "A");
        map.put(3, "A");
        map.put(8, "A");
        map.put(5, "A");
        //原始顺序
        System.out.println("原始顺序:");
        for (Object o : map.entrySet()) {
            System.out.printf("%s ", o);
        //gson
        Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        String gJson = gson.toJson(map);
        Map m = gson.fromJson(gJson, Map.class);
        System.out.println();
        System.out.println("gson:");
        for (Object o : m.entrySet()) {
            System.out.printf("%s ", o);
原始顺序:
1=A 3=A 8=A 5=A 
gson:
1=A 3=A 8=A 5=A

方法2: fastjson版本升级到1.2.3以上, 指定Feature.OrderedField参数

代码示例:

//fastjson
String fJson = JSON.toJSONString(map);
Map m = JSON.parseObject(fJson, Feature.OrderedField);
System.out.println();
System.out.println("fastjson:");
for (Object o : m.entrySet()) {
    System.out.printf("%s ", o);
原始顺序:
1=A 3=A 8=A 5=A 
fastjson:
1=A 3=A 8=A 5=A
根据JSON.parseObject(fJson, Feature.OrderedField),传入的Feature.OrderedField会使ordered=true,这样返回的map对象是LinkedHashMap类型,put的时候就会保证key的顺序。

com.alibaba.fastjson.JSONObject#JSONObject(int, boolean)

    public JSONObject(int initialCapacity, boolean ordered) {
        if (ordered) {
            this.map = new LinkedHashMap(initialCapacity);
        } else {
            this.map = new HashMap(initialCapacity);

cloud.tencent.com/developer/a… www.cnblogs.com/hujiapeng/p…

分类:
后端
标签: