场景:业务端传输JSONObject有父子关系(由于在接收处理时必须有父级才能在父级下生成相应的子级,因此从业务端接收JSON排序处理优先级高的,逐级处理)
对应报文:(其中uid为当前节点id,puid为父级节点id,当puid为空时则意味着当前级次为顶级)
//报文样例 {
"list": [{
"uid": "98bb44a3218b42c79041cded977078ac", "puid": "" }, {
"uid": "2348fac8369041d08597d5905b159b0d", "puid": "98bb44a3218b42c79041cded977078ac" }, {
"uid": "f4f512e24f7443ff933e201abbe12e29", "puid": "98bb44a3218b42c79041cded977078ac" }, {
"uid": "e2e3da924f3f41058a638ced2ed4a76a", "puid": "418b228d17254b0a857e05468645d3e6" }, {
"uid": "96fc479788f844e9815447bcd82bca31", "puid": "ccaaacb14899446ca4b2d7c290d51974" }, {
"uid": "418b228d17254b0a857e05468645d3e6", "puid": "" }, {
"uid": "b3feab13d5ca4511935ba90e1b348ab2", "puid": "96fc479788f844e9815447bcd82bca31" }, {
"uid": "23becdf5d97d4cbf8108eaaeab0769e6", "puid": "b3feab13d5ca4511935ba90e1b348ab2" }, {
"uid": "03de11550b1b402d8a591855f47b86e9", "puid": "b3feab13d5ca4511935ba90e1b348ab2" }, {
"uid": "ccaaacb14899446ca4b2d7c290d51974",
"puid": ""
}]
}
最终想达成的效果:(让父级一定在子级上,读取的时候先生成父级再生成子级)
{
"list": [{
"uid": "98bb44a3218b42c79041cded977078ac",
"puid": "",
"level": 1
}, {
"uid": "418b228d17254b0a857e05468645d3e6",
"puid": "",
"level": 1
}, {
"uid": "ccaaacb14899446ca4b2d7c290d51974",
"puid": "",
"level": 1
}, {
"uid": "2348fac8369041d08597d5905b159b0d",
"puid": "98bb44a3218b42c79041cded977078ac",
"level": 2
}, {
"uid": "f4f512e24f7443ff933e201abbe12e29",
"puid": "98bb44a3218b42c79041cded977078ac",
"level": 2
}, {
"uid": "e2e3da924f3f41058a638ced2ed4a76a",
"puid": "418b228d17254b0a857e05468645d3e6",
"level": 2
}, {
"uid": "96fc479788f844e9815447bcd82bca31",
"puid": "ccaaacb14899446ca4b2d7c290d51974",
"level": 2
}, {
"uid": "b3feab13d5ca4511935ba90e1b348ab2",
"puid": "96fc479788f844e9815447bcd82bca31",
"level": 3
}, {
"uid": "23becdf5d97d4cbf8108eaaeab0769e6",
"puid": "b3feab13d5ca4511935ba90e1b348ab2",
"level": 4
}, {
"uid": "03de11550b1b402d8a591855f47b86e9",
"puid": "b3feab13d5ca4511935ba90e1b348ab2",
"level": 4
}]
}
想法: 首先想到了递归,所以想了第一套方案 方案一:(将第一层父节点首先进行确定然后让后续的分为第二层到第n层,此方法for循环嵌套效率极差,故弃用此方案,想了第二套方案)
private List<JSONObject> jsonSort(List<JSONObject> listJsonArrayBiz_sort,int x){
boolean isfor = false;//此标识用于标记是否会存在断级的情况,避免错误数据的产生
for(int i = 0;i<listJsonArrayBiz_sort.size();i++){
JSONObject son_sort = listJsonArrayBiz_sort.get(i);
if(son_sort.containsKey("level")){
continue;
}else{
String puid = son_sort.getString("puid");
if(puid.equals("")){
//确定第一层父节点,定为一级
son_sort.put("level", 1);
isfor = true;
continue;
}
if(x != 1){
//在二级往后进入
for(int j = 0;j<listJsonArrayBiz_sort.size();j++){
JSONObject parent_sort = listJsonArrayBiz_sort.get(j);
if(parent_sort.containsKey("level") && parent_sort.getInteger("level") == x-1){
//查找上级是否存在
if(parent_sort.containsKey("uid") && puid.equals(parent_sort.get("uid"))){
son_sort.put("level", x);
isfor = true;
break;
}
}
}
}
}
}
if(isfor){
jsonSort(listJsonArrayBiz_sort,x+1);
}
return listJsonArrayBiz_sort;
}
方案二:(此方案将uid拼接成长id形式以-进行连接,最后进行排序,将父级放在子级前,最终选用此方案)
/** * 对List<JSONObject>相关字段排序 */
public void sort(List<JSONObject> infos) {
Map<String, JSONObject> datas = new HashMap<String, JSONObject>();// 待处理数据集合
Map<String, JSONObject> result = new HashMap<String, JSONObject>();// 结果数据集合
Map<String, List<String>> pids = new HashMap<String, List<String>>();// 上级数据集合
// 初始化数据到相关集合
infos.forEach(v -> {
String uid = v.getString("uid");
String puid = v.getString("puid");
if (puid == null || "".equals(puid)) {
result.put(uid, v);
} else {
datas.put(uid, v);
List<String> uids = new ArrayList<String>();
if (pids.containsKey(puid)) {
uids = pids.get(puid);
}
uids.add(uid);
pids.put(puid, uids);
}
});
// 处理错误数据到结果结合
pids.forEach((k, v) -> {
if (!result.containsKey(k) && !datas.containsKey(k)) {
v.forEach(uid -> {
JSONObject data = datas.get(uid);
result.put(uid, data);
datas.remove(uid);
});
}
});
Map<String, String> mapping = new HashMap<String, String>();
int level = 1;
bulid(result, datas, mapping, level);
List<String> ks = new ArrayList<String>(result.keySet());
Collections.sort(ks);
List<JSONObject> infos_sort = new ArrayList<JSONObject>();
ks.forEach(k -> {
infos_sort.add(result.get(k));
});
infos.removeAll(infos);
infos.addAll(infos_sort);
}
public void bulid(Map<String, JSONObject> result, Map<String, JSONObject> datas, Map<String, String> mapping,
int level) {
Map<String, JSONObject> _datas = new HashMap<String, JSONObject>();
Collection<JSONObject> values = datas.values();
if (values.size() == 0 || level > 20) {
return;
}
datas.values().forEach(v -> {
String uid = v.getString("uid");
String puid = v.getString("puid");
if (mapping.containsKey(puid)) {
puid = mapping.get(puid);
}
if (result.containsKey(puid)) {
String key = puid + "-" + uid;
mapping.put(uid, key);
result.put(key, v);
} else {
_datas.put(uid, v);
}
});
level++;
bulid(result, _datas, mapping, level);
}
不知是否有更好的解决方案,先在此记录两种方案,后续如有更好的方案再进行补充。