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然后传递给前端。
最重要的构造器是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