最近项目中用到Json排序的算法。也就是用拿到一段json字符串,按照key的ASCII值进行排序,但是对应的Value值不能变化,由于value值的类型有很多数据类型,所以在排序的时候有可能处理的不是很好。下面我是用栈Stack来对Json字符串进行排序,当然里面包含Json数组的排序。里面当然也涉及到递归算法。
算法如下,我将代码贴出来。
/*
* 未加密的Json进行排序
* @param rawJsonString 不带mac签名的Json字符串
* @return jsonString 排序后的Json字符串
*/
public static String rawPayloadSort(String rawJsonString){
//去掉最前面{和最后面}
rawJsonString = rawJsonString.substring(rawJsonString.indexOf("{") + 1,rawJsonString.lastIndexOf("}"));
String[] strSplit = rawJsonString.split(",");
String arrString = "";
// jsonKey
String jsonKey = "";
String jsonValue = "";
List<String> keyList = new ArrayList<String>();
Map<String, String> map = new HashMap<String, String>();
Stack<Integer> stack = new Stack<Integer>();
Stack<Integer> stackArrayJson = new Stack<Integer>();
Stack<Integer> stackJson = new Stack<Integer>();
int stackCount = 0;
// 配对{}的临时字符串
String tmpString = "";
for (int i = 0;i<strSplit.length;i++) {
// Json数组优先判断
arrString = strSplit[i];
if(arrString.indexOf("{") != -1 && arrString.indexOf("[") != -1 && (arrString.indexOf("{") > arrString.indexOf("[")) || !stackArrayJson.empty()) {
// 中括号 配对压栈
for(int j = 0; j < arrString.length(); j++){
char c = arrString.charAt(j);
if (c == '['){
stackArrayJson.add(stackCount++);
}
if (c == ']') {
stackArrayJson.pop();
}
}
if (!stackArrayJson.empty()) {
tmpString = tmpString + arrString + ",";
continue;
} else {
tmpString = tmpString + arrString;
arrString = tmpString;
tmpString = "";
}
} else if(arrString.indexOf("{") != -1 && arrString.indexOf("[") != -1 && (arrString.indexOf("{") > arrString.indexOf("[")) || !stack.empty()){
for(int j = 0; j < arrString.length(); j++){
char c = arrString.charAt(j);
if (c == '{'){
stack.add(stackCount++);
}
if (c == '}') {
stack.pop();
}
}
if (!stack.empty()) {
tmpString = tmpString + arrString + ",";
continue;
} else {
tmpString = tmpString + arrString;
arrString = tmpString;
tmpString = "";
}
}else if((arrString.indexOf("{") != -1 && arrString.indexOf("[") == -1) || !stackJson.empty()){
for(int j = 0; j < arrString.length(); j++){
char c = arrString.charAt(j);
if (c == '{'){
stackJson.add(stackCount++);
}
if (c == '}') {
stackJson.pop();
}
}
if (!stackJson.empty()) {
tmpString = tmpString + arrString + ",";
continue;
} else {
tmpString = tmpString + arrString;
arrString = tmpString;
tmpString = "";
}
}
// 取得键值对
jsonKey = arrString.substring(0,arrString.indexOf(":"));
jsonValue = arrString.substring(arrString.indexOf(":") + 1);
if(jsonValue.indexOf("[") == -1 && jsonValue.indexOf("]") == -1 && jsonValue.indexOf("{") != -1) {
String sortedJsonString = rawPayloadSort(jsonValue);
map.put(jsonKey, sortedJsonString);
keyList.add(jsonKey);
} else if (jsonValue.indexOf("[") != -1 && jsonValue.indexOf("]") != -1 && jsonValue.indexOf("{") != -1){
// 先去掉前后[]
jsonValue = jsonValue.substring(jsonValue.indexOf("[") + 1,jsonValue.lastIndexOf("]"));
String[] strSplitJson = jsonValue.split(",");
Stack<Integer> stackArray = new Stack<Integer>();
String tmpStringArray = "";
String arrStringArray = "";
List<String> listJson = new ArrayList<String>();
for (int j = 0; j < strSplitJson.length; j++){
arrStringArray = strSplitJson[j];
if(arrStringArray.indexOf("{") != -1 || !stackArray.empty()) {
// 数组组成个数 配对压栈
for(int k = 0; k < arrStringArray.length(); k++){
char c = arrStringArray.charAt(k);
if (c == '{'){
stackArray.add(stackCount++);
}
if (c == '}') {
stackArray.pop();
}
}
if (!stackArray.empty()) {
tmpStringArray = tmpStringArray + arrStringArray + ",";
continue;
} else {
tmpStringArray = tmpStringArray + arrStringArray;
tmpStringArray = rawPayloadSort(tmpStringArray);
listJson.add(tmpStringArray);
tmpStringArray = "";
}
}
}
Collections.sort(listJson);
int countJson = 0;
StringBuilder arrayJson = new StringBuilder();
for (int m = 0; m< listJson.size(); m++) {
arrayJson.append(listJson.get(m));
countJson ++;
if(countJson != listJson.size()) {
arrayJson.append(",");
}
}
map.put(jsonKey, "[" + arrayJson + "]");
keyList.add(jsonKey);
} else {
map.put(jsonKey, jsonValue);
keyList.add(jsonKey);
}
}
Collections.sort(keyList);
StringBuilder sb = new StringBuilder();
int flag=0;
sb.append("{");
for (String str : keyList) {
sb.append(str+":"+map.get(str));
flag++;
if(flag!=keyList.size()){
sb.append(",");
}
}
sb.append("}");
String jsonString = sb.toString();
return jsonString;
}
对上面的算法进行Junit测试,执行后的结果如下:
测试1 原Json:{"loginName":"test123","loginPassword":"123abc","udid":"123"}
测试1 排序后:{"loginName":"test123","loginPassword":"123abc","udid":"123"}
测试2 原Json:{"tim":"223344","tim1":{"ti12":33333,"ti":null,"ti1":"2222"}}
测试2 排序后:{"tim":"223344","tim1":{"ti":null,"ti1":"2222","ti12":33333}}
测试6 原Json:{"tim":"223344","tim1":{"ti12":33333,"ti1":{"ret":33333,"wwe":null,"hjy":"2222"},"ti":null}}
测试6排序后:{"tim":"223344","tim1":{"ti":null,"ti1":{"hjy":"2222","ret":33333,"wwe":null},"ti12":33333}}
测试7 原Json:{"tim":"223344","tim1":{"ti12":33333,"ti1":{"ret":33333},"ti":null}}
测试7排序后:{"tim":"223344","tim1":{"ti":null,"ti1":{"ret":33333},"ti12":33333}}
测试8 原Json:{"tim":"223344","tim1":{"ti1":{"ret":33333},"ti12":33333,"ti":null} }
测试8排序后:{"tim":"223344","tim1":{"ti":null,"ti1":{"ret":33333},"ti12":33333}}
测试3 原Json:{"a2": null,"a1": {"c3": 434,"c1": "sfefs3","c2": "sfsfe22"},"a3": [{"p3":"ppp"},{"p1": "pqr"},{"p2": "ffff"}]}
测试3 排序后:{"a1":{"c1": "sfefs3","c2": "sfsfe22","c3": 434},"a2": null,"a3":[{"p1": "pqr"},{"p2": "ffff"},{"p3":"ppp"}]}
测试4原Json:{"a2": "23312123","a1": {"c3": "434","c1": "sfefs3","c2": "sfsfe22"},"a3": [{"p3":"ppp"},{"opppppp": "434","xxxh": "sfefs3","xxxilll": "sfsfe22"},{"q2": "ffff"}]}
测试4 排序后:{"a1":{"c1": "sfefs3","c2": "sfsfe22","c3": "434"},"a2": "23312123","a3":[{"opppppp": "434","xxxh": "sfefs3","xxxilll": "sfsfe22"},{"p3":"ppp"},{"q2": "ffff"}]}
测试5 原Json:{"walletID": "","accessToken": "","cards": [{"id": null,"cardNo": "121132","faceValue": null,"frozenValue": null,"balanceValue": null,"type": null,"status": null,"frozenAt": null,"walletId": null,"order": 1,"alias": "lol卡","isForbidden": 0,"bindCardAt": null,"currentDate": null,"createdAt": null,"issueId": null,"isPasswordModified": null,"cardSN": null}]}
测试5 排序后:{"accessToken": "","cards":[{"alias": "lol卡","balanceValue": null,"bindCardAt": null,"cardNo": "121132","cardSN": null,"createdAt": null,"currentDate": null,"faceValue": null,"frozenAt": null,"frozenValue": null,"id": null,"isForbidden": 0,"isPasswordModified": null,"issueId": null,"order": 1,"status": null,"type": null,"walletId": null}],"walletID": ""}
转载于:https://blog.51cto.com/gunxueqiu/1571231