List<JSONObject>有上下级关联时排序处理

场景:业务端传输的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);
    }

不知是否有更好的解决方案,先在此记录两种方案,后续如有更好的方案再进行补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值