Android的JSONObject 使用HashMap来存储key-value
public JSONObject() {
nameValuePairs = new HashMap<String, Object>();
}
JSONObject.toString 通过遍历HashMap来输出一个个key-value
public String toString(int indentSpaces) throws JSONException {
JSONStringer stringer = new JSONStringer(indentSpaces);
writeTo(stringer);
return stringer.toString();
}
void writeTo(JSONStringer stringer) throws JSONException {
stringer.object();
for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
stringer.key(entry.getKey()).value(entry.getValue());
}
stringer.endObject();
}
从中看出HashMap.entrySet()的遍历顺序决定了输出json字符串的key-value顺序。 而HashMap是由数组+链表构成,如果阅读HashMap源码就知道,这个顺序取决于三个因素:key, 插入顺序,HashMap的当前长度。 因此对同样一组key-value生成Json字符串就有两个因素决定:插入循序,HashMap当前长度。
开发中最容易忽略的一种插入循序导致json字符串不同的例子
String key1 = "due_time";
String value1 = "0";
String key2 = "attachment";
String value2 = "a.jpg";
try {
JSONObject json1 = new JSONObject();
json1.put(key1, value1);
json1.put(key2, value2);
Log.d("test", "json1:" + json1.toString());
JSONObject json2 = new JSONObject(json1.toString());
Log.d("test", "json2:" + json2.toString());
} catch (Exception e) {
}
输出的结果:
D/test ( 9577): json1:{"attachment":"a.jpg","due_time":"0"}
D/test ( 9577): json2:{"due_time":"0","attachment":"a.jpg"}
因此解决上述需求,大家可以使用fastjson,他输出的字符串是以key排序的。
关于fastjson的获取可见:
https://github.com/alibaba/fastjson/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98