最近项目中用到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": ""}