java中关于JSONObject顺序排序的问题

JSONObject put数据之后,排序会发生变化。

  如下放入JSONObject中数据,  

  JSONObject object=new JSONObject();    

   object.put("aaa",111);    

   object.put("bbb",222);    

   object.put("ccc",333);  

   object.put("ddd",444); 

取出来的时候,可能为以下:

{"aaa":111,"ddd":444,"ccc":333,"bbb":222} 

因为JsonObject内部是用Hashmap来存储的,所以输出是按key的排序来的,如果要让JsonObject按固定顺序(put的顺序)排列,可以修改JsonObject的定义HashMap改为LinkedHashMap。

public JSONObject() {  
        this.map = new LinkedHashMap();  //new HashMap();  
}  

即定义JsonObject可以这样:JSONObject jsonObj =new JSONObject(newLinkedHashMap());

这样定义的JSONObject对象就能满足顺序不变的要求了。

注意:

1. java中生成的JSONObject,如果转成string后,传到js中,则顺序还不会变化,但是在js中将这个string转成js的JsonObject对象后,顺序又变化了!

2.JSONArray中对象的顺序是不会变化的,也就是put进去的时候是什么顺序,取的时候就是什么顺序。

什么场景下会对这个JSONObject顺序由要求呢?

当我们计算签名时,如果使用到了json做中间的转换的时候,就一定会出现顺序不一样而导致计算出来的签名不一致的问题。

怎么解决这个问题呢?如下图所示:

JSONObject jsonObject1 = new JSONObject(); //无序的HashMap
JSONObject jsonObject2 = new JSONObject(true); //有序设置方法一,LinkedHashMap
JSONObject jsonObject3 = new JSONObject(new LinkedHashMap<>()); //有序设置方法二

相信你已经知道怎么解决了。

 

在android sdk中,谷歌已经解决了JSONObject的这个问题

    @UnsupportedAppUsage
    private final LinkedHashMap nameValuePairs;

    /**
     * Creates a {@code JSONObject} with no name/value mappings.
     */
    public JSONObject() {
        nameValuePairs = new LinkedHashMap();
    }

JSON(JavaScript Object Notation的首字母缩写)是一种轻量级数据交换格式,最常用于客户端 - 服务器通信。它既易于读/写,又与语言无关。JSON值可以是另一个JSON 对象,数组,数字,字符串,布尔值(true / false)或null。也是后端开发中经常要接触的一个一个类,将要数据封装成json然后传递给前端。

JSONObject的构造器

在这里插入图片描述
最重要的构造器是public JSONObject(int initialCapacity, boolean ordered),其他构造器都直接调用此构造器。initialCapacity为初始容量,ordered为map是否有序

	//构造容量为16个单位的HashMap作为JSONObject
	public JSONObject(){
		//调用public JSONObject(int initialCapacity, boolean ordered)
        this(DEFAULT_INITIAL_CAPACITY, false);
    }
	//构造自定义Map 容器类型的JSONObject
    public JSONObject(Map map){
        if (map == null) {
            throw new IllegalArgumentException("map is null.");
        }
        this.map = map;
    }
	//构造容量为16个单位JSONObject,可选择器容器是否有序:LinkedHashMap(true)、HashMap(false)
    public JSONObject(boolean ordered){
        this(DEFAULT_INITIAL_CAPACITY, ordered);
    }
	//构造自定义初始大小的HashMap类型的JSONObject
    public JSONObject(int initialCapacity){
        this(initialCapacity, false);
    }

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

使用示例:

	//构造容量为16个单位的HashMap作为JSONObject
    JSONObject jsonObject = new JSONObject();
    
    //构造容量为16个单位JSONObject,可选择器容器是否有序:LinkedHashMap(true)、HashMap(false)
    JSONObject jsonObject1 = new JSONObject(true);
    
     //构造自定义Map 容器类型的JSONObject
    Map map = new ConcurrentHashMap<>(16);
    JSONObject jsonObject2 = new JSONObject(map);
    
    //自定义
    JSONObject jsonObject3 = new JSONObject(32, false);

源码解读请参考:https://blog.csdn.net/Butterfly_resting/article/details/100053544

 

 

你可能感兴趣的:(java点滴)