平级数据处理成树数据工具类

此工具类支持如下功能点:

1、平级数据递归处理成树数据

2、支持设定子级集合名称

3、支持设定多个排序字段

4、支持返回某个节点下的子级集合树数据

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.util.Comparator;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author :yangwang
 * @description:平级数据处理成树数据工具类
 * @email 1187493980@qq.com
 *        shuiyuetianwy@gmaill.com
 * @date :2021/12/27 16:02
 */
public class HandleToTreeUtils {

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @return JSONArray 结果集
     */
    public static JSONArray handleToTree(JSONArray dataArr){
        JSONArray resultJson = new JSONArray();
        recursionHandleToTree(resultJson,dataArr,null,null);
        return resultJson;
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @return JSONArray 结果集
     */
    public static JSONArray handleToTree(JSONArray dataArr,String curId){
        JSONArray resultJson = new JSONArray();
        recursionHandleToTree(resultJson,dataArr,curId,null);
        return resultJson;
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @param sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     * @return JSONArray 结果集
     *
     */
    public static JSONArray handleToTree(JSONArray dataArr,Object... sortObjs){
        JSONArray resultJson = new JSONArray();
        recursionHandleToTree(resultJson,dataArr,null,null,sortObjs);
        return resultJson;
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @param childsName 子级集合名称(默认-childs)
     * @return JSONArray 结果集
     */
    public static JSONArray handleToTree(JSONArray dataArr,String curId,String childsName){
        JSONArray resultJson = new JSONArray();
        recursionHandleToTree(resultJson,dataArr,curId,childsName);
        return resultJson;
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @param sortObjs 排序对象
     *       [{"name":"","isAsc":false},{"name":""}]
     *       name 排序字段名称
     *       isAsc true-升序(默认),false-倒叙
     * @return JSONArray 结果集
     */
    public static JSONArray handleToTree(JSONArray dataArr,String curId,Object... sortObjs){
        JSONArray resultJson = new JSONArray();
        recursionHandleToTree(resultJson,dataArr,curId,null,sortObjs);
        return resultJson;
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @param childsName 子级集合名称(默认-childs)
     * @param sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     * @return JSONArray 结果集
     */
    public static JSONArray handleToTree(JSONArray dataArr,String curId,String childsName,Object... sortObjs){
        JSONArray resultJson = new JSONArray();
        recursionHandleToTree(resultJson,dataArr,curId,childsName,sortObjs);
        return resultJson;
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     */
    public static void handleToTree(JSONArray resultJson, JSONArray dataArr){
        recursionHandleToTree(resultJson,dataArr,null,null);
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *        必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     */
    public static void handleToTree(JSONArray resultJson, JSONArray dataArr,String curId){
        recursionHandleToTree(resultJson,dataArr,curId,null);
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *        必含字段:id-主键,parentId-父级id
     * @param sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     */
    public static void handleToTree(JSONArray resultJson, JSONArray dataArr,Object... sortObjs){
        recursionHandleToTree(resultJson,dataArr,null,null,sortObjs);
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *        必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @param childsName 子级集合名称(默认-childs)
     */
    public static void handleToTree(JSONArray resultJson, JSONArray dataArr,String curId,String childsName){
        recursionHandleToTree(resultJson,dataArr,curId,childsName);
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *        必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @param sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     */
    public static void handleToTree(JSONArray resultJson, JSONArray dataArr,String curId,Object... sortObjs){
        recursionHandleToTree(resultJson,dataArr,curId,null,sortObjs);
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *        必含字段:id-主键,parentId-父级id
     * @param curId 当前节点id
     * @param childsName 子级集合名称(默认-childs)
     * @param sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     */
    public static void handleToTree(JSONArray resultJson, JSONArray dataArr,String curId,String childsName,Object... sortObjs){
        recursionHandleToTree(resultJson,dataArr,curId,childsName,sortObjs);
    }

    /**
     * @description: 递归处理为树结构
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param resultJson 结果集
     * @param dataArr 原始数据
     *       必含字段:id-主键,parentId-父级id
     * @param curId 节点id
     * @param childsName 子级集合名称(默认-childs)
     * @param sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     */
    private static void recursionHandleToTree(JSONArray resultJson, JSONArray dataArr, String curId, String childsName,Object... sortObjs){
        if((null!=dataArr)&&(0<dataArr.size())){
            //按orgId筛选
            if(StringUtils.isNotBlank(curId)){
                //获取当前对象下子级
                JSONArray childJson = dataArr.stream().filter(d -> {
                    if(null!=d){
                        JSONObject dObj = (JSONObject) d;
                        if((null!=dObj)&&(dObj.containsKey("id"))&&(dObj.containsKey("parentId"))&&(StringUtils.equals(dObj.getString("parentId"),curId))){
                            return true;
                        }
                    }
                    return false;
                })
                .sorted(new DataSortComparator(sortObjs))
                .collect(Collectors.toCollection(JSONArray::new));
                if((null!=childJson)&&(0<childJson.size())){
                    JSONObject dataObj =null;
                    JSONArray levelTwoJson =null;
                    for(Object data:childJson){
                        if(null != data){
                            dataObj = (JSONObject) data;
                            if((null!=dataObj)&&(dataObj.containsKey("id"))&&(StringUtils.isNotBlank(dataObj.getString("id")))){
                                levelTwoJson = new JSONArray();
                                //递归处理子级为树结构
                                recursionHandleToTree(levelTwoJson,dataArr,dataObj.getString("id"),childsName,sortObjs);
                                if((null!=levelTwoJson)&&(0<levelTwoJson.size())){
                                    //去重排序
                                    levelTwoJson = levelTwoJson.stream().distinct().filter(d -> {
                                        if(null!=d){
                                            JSONObject dObj = (JSONObject) d;
                                            if((null!=dObj)&&(dObj.containsKey("id"))&&(StringUtils.isNotBlank(dObj.getString("id")))){
                                                return true;
                                            }
                                        }
                                        return false;
                                    })
                                    .sorted(new DataSortComparator(sortObjs))
                                    .collect(Collectors.toCollection(JSONArray::new));
                                    dataObj.put(((StringUtils.isNotBlank(childsName))?childsName:"childs"),levelTwoJson);
                                }else{
                                    dataObj.put(((StringUtils.isNotBlank(childsName))?childsName:"childs"),new JSONArray());
                                }
                                //保存当前对象到结果集
                                resultJson.add(dataObj);
                            }
                        }
                    }
                }
            }else{
                JSONObject dataObj =null;
                JSONObject topObj =null;
                Optional<Object> existOpt =null;
                JSONArray childJson =null;
                for(Object data:dataArr){
                    if(null != data){
                        dataObj = (JSONObject) data;
                        if((null!=dataObj)&&(dataObj.containsKey("id"))&&(StringUtils.isNotBlank(dataObj.getString("id")))){
                            topObj = new JSONObject();
                            if((dataObj.containsKey("parentId"))&&(StringUtils.isNotBlank(dataObj.getString("parentId")))){
                                //检索顶级组织节点
                                topObj = findTopOrgNode(dataArr,dataObj.getString("parentId"));
                            }
                            if((null==topObj)||(!topObj.containsKey("id"))||    (StringUtils.isBlank(topObj.getString("id")))){
                                topObj = dataObj;
                            }
                            if(null!=topObj){
                                //判断是否存在
                                Boolean existFlag = false;
                                if((null!=resultJson)&&(0<resultJson.size())){
                                    String topOrgId = topObj.getString("id");
                                    existOpt = resultJson.stream().filter(s -> {
                                        if(null!=s){
                                            JSONObject dObj = (JSONObject) s;
                                            if((null!=dObj)&&(dObj.containsKey("id"))&&(StringUtils.isNotBlank(dObj.getString("id")))&&(StringUtils.equals(dObj.getString("id"),topOrgId))){
                                                return true;
                                            }
                                        }
                                        return false;
                                    }).findAny();
                                    existFlag = existOpt.isPresent();
                                }
                                if(! existFlag){
                                    childJson = new JSONArray();
                                    //递归处理子级为树结构
                                    recursionHandleToTree(childJson,dataArr,topObj.getString("id"),childsName,sortObjs);
                                    topObj.put(((StringUtils.isNotBlank(childsName))?childsName:"childs"),childJson);
                                    resultJson.add(topObj);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * @description: 检索顶级节点
     * @author: yangwang
     * @date: 2021/12/27 16:07
     * @param dataArr 原始数据
     * @param curId 当前节点id
     * @return JSONObject
     */
    private static JSONObject findTopOrgNode(JSONArray dataArr,String curId){
        if(StringUtils.isNotBlank(curId)){
            Optional<Object> parentOpt = dataArr.stream().distinct().filter(d -> {
                if(null!=d){
                    JSONObject dObj = (JSONObject) d;
                    if((null!=dObj)&&(dObj.containsKey("id"))&&(StringUtils.isNotBlank(dObj.getString("id")))&&(StringUtils.equals(dObj.getString("id"),curId))){
                        return true;
                    }
                }
                return false;
            }).findAny();
            if(parentOpt.isPresent()){
                JSONObject dataObj = (JSONObject) parentOpt.get();
                if((null!=dataObj)&&(dataObj.containsKey("id"))&&(StringUtils.isNotBlank(dataObj.getString("id")))){
                    if((dataObj.containsKey("parentId"))&&(StringUtils.isNotBlank(dataObj.getString("parentId")))){
                        JSONObject parentObj = findTopOrgNode(dataArr,dataObj.getString("parentId"));
                        return (null!=parentObj)?parentObj:dataObj;
                    }
                    return dataObj;
                }
            }
        }

        return null;
    }

    /**
     * @description: 数据排序比较器
     *      sortObjs 排序对象
     *      [{"name":"","isAsc":false},{"name":""}]
     *      name 排序字段名称
     *      isAsc true-升序(默认),false-倒叙
     * @author: yangwang
     * @date: 2021/12/27 17:27
     */
    public static class DataSortComparator implements Comparator<Object>{
        /*排序对象*/
        private Object[] sortObjs;

        public DataSortComparator(Object[] sortObjs){
            super();
            this.sortObjs = sortObjs;
        }

        @Override
        public int compare(Object before, Object after) {
            int compareInt = 0;
            if((null!=sortObjs)&&(0 < sortObjs.length)&&(null!=before)&&(null!=after)){
                JSONObject sortObj =null;
                JSONObject objOne = null;
                JSONObject objTwo = null;
                for(Object obj:sortObjs){
                    if(null!=obj){
                        sortObj = (JSONObject) obj;
                        if((null!=sortObj)&&(sortObj.containsKey("name"))){
                            objOne = ((sortObj.containsKey("isAsc"))&&(!sortObj.getBoolean("isAsc")))?(JSONObject) after:(JSONObject) before;
                            objTwo = ((sortObj.containsKey("isAsc"))&&(!sortObj.getBoolean("isAsc")))?(JSONObject) before:(JSONObject) after;
                            if((objOne.containsKey(sortObj.getString("name")))&&(null != objOne.get(sortObj.getString("name")))&&(objTwo.containsKey(sortObj.getString("name")))&&(null != objTwo.get(sortObj.getString("name")))){
                                try {
                                    compareInt = (new Double(objOne.getDoubleValue(sortObj.getString("name")))).compareTo(new Double(objTwo.getDoubleValue(sortObj.getString("name"))));
                                }catch (Exception e){
                                    compareInt = (objOne.getString(sortObj.getString("name"))).compareTo(objTwo.getString(sortObj.getString("name")));
                                }
                                if(0 == compareInt){
                                    continue;
                                }else{
                                    return compareInt;
                                }
                            }
                        }
                    }
                }
            }
            return compareInt;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值