树形数据工具类(所有类别可用)

这是一个Java工具类,用于将列表数据转换为树形结构。通过泛型和反射实现,适用于任何具有id、parent_id和子节点集合属性的实体类。主要方法包括start(),用于初始化转化,changeTree()进行递归构建树形结构,以及辅助方法如doChangeTree()。示例代码展示了如何使用该工具类。
摘要由CSDN通过智能技术生成

粘贴即用,欢迎使用
树形数据工具类(泛型+反射->所有类别可用)

package com.record.util;

import com.record.auth.entity.SysMenu;
import com.sun.xml.internal.messaging.saaj.soap.impl.TreeException;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 公共树形工具转化类
 * 详细用法以下有main方法示例
 * 实体类中若需要看打印则需要tostring方法
 * @author 丁建荣
 * @param <T>
 */
@Component
public class TreeUtil<T> {
    /**
     * 公共转化
     * @param list -- 传入的实体集合
     * @param menuEntityName  -- 在实体类中id的名称
     * @param pMenuEntityName -- 在实体类中父id的名称
     * @param childEntityName -- 在实体类中子集合的名称
     * @param rootValue -- (根)第一节点的参考值
     * @return
     */
    public List<T> start(List<T> list,String menuEntityName,String pMenuEntityName,String childEntityName,String rootValue){
        //参数判空
        try {
            if(ProcessingCheck.isEmpty(list)){
                    throw new TreeUtilException("传入集合不能为空");
            }
            if(ProcessingCheck.isEmpty(menuEntityName)){
                    throw new TreeUtilException("标识属性名称不能为空");
            }
            if(ProcessingCheck.isEmpty(pMenuEntityName)){
                    throw new TreeUtilException("父级标识属性名称不能为空");
            }
            if(ProcessingCheck.isEmpty(childEntityName)){
                    throw new TreeUtilException("子集属性名称不能为空");
            }
            if(ProcessingCheck.isEmpty(rootValue)){
                    throw new TreeUtilException("根节点值不能为空");
            }
        } catch (TreeUtilException e) {
            e.printStackTrace();
            return null;
        }
        //获取根节点集合
        List<T> pList = list.stream().filter(a -> rootValue.equals(ReflexOperation.getFieldValueByName(pMenuEntityName, a))).collect(Collectors.toList());
        //移除根节点集合
        list.removeAll(pList);
        //调用递归返回最终结果
        return  changeTree(pList,list,menuEntityName,pMenuEntityName,childEntityName);
    }

    /**
     * 解析属性结构数据生成树形集合
     */
    public List<T> changeTree(List<T> pList,List<T> list,String menuEntityName,String pMenuEntityName,String childEntityName){
        for(int i=0;i<pList.size();i++) {
            T p = pList.get(i);
            //初始化即将存入实体类子集的集合数据
            List<T> childrenList = new ArrayList<>();
            //获取字段属性值
            Field filed = ReflexOperation.getFiled(childEntityName, p);
            //设置允许访问对象
            filed.setAccessible(true);
            //遍历插入
            List<T> collect = list.stream().filter(c ->
                            null!=ReflexOperation.getFieldValueByName(menuEntityName, p)&&null!=ReflexOperation.getFieldValueByName(pMenuEntityName, c)&&
                    ReflexOperation.getFieldValueByName(menuEntityName, p).equals(ReflexOperation.getFieldValueByName(pMenuEntityName, c))).collect(Collectors.toList());
            collect.stream().forEach(d -> {
                //初始化执行状态
                boolean statu=true;
                if(null != list && list.size() > 0){
                    statu=true;
                }else{
                    statu=false;
                }
                //去除已经被使用的实体
                list.remove(d);
                if (statu) {
                    //递归调用形成子集实体的子集集合
                    d = this.doChangeTree(d, list, menuEntityName, pMenuEntityName, childEntityName);
                    //添加对应子集实体
                    childrenList.add(d);
                }
            });
            //将子集集合插入父实体中
            try {
                filed.set(p, childrenList);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            //设置不允许对象访问
            filed.setAccessible(false);
        }
        return pList;
    }

    /**
     * 递归调用方法
     */
    public T doChangeTree(T t,List<T> list,String menuEntityName,String pMenuEntityName,String childEntityName){
        //初始化即将存入实体类子集的集合数据
        List<T> childrenList=new ArrayList<>();
        //获取字段属性值
        Field filed = ReflexOperation.getFiled(childEntityName, t);
        //设置允许访问对象
        filed.setAccessible(true);
        List<T> collect = list.stream().filter(a ->
                null!=ReflexOperation.getFieldValueByName(menuEntityName, t)&&null!=ReflexOperation.getFieldValueByName(pMenuEntityName, a)&&
                ReflexOperation.getFieldValueByName(menuEntityName, t).equals(ReflexOperation.getFieldValueByName(pMenuEntityName, a))).collect(Collectors.toList());
        collect.stream().forEach(b->{
            //初始化执行状态
            boolean statu=true;
            if(null != list && list.size() > 0){
                statu=true;
            }else{
                statu=false;
            }
            //去除已经被使用的实体
            list.remove(b);
            if(statu){
                //递归调用形成子集实体的子集集合
                b=this.doChangeTree(b,list,menuEntityName,pMenuEntityName,childEntityName);
                //添加对应子集实体
                childrenList.add(b);
            }
        });
        //将子集集合插入父实体中
        try {
            filed.set(t,childrenList);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //设置不允许对象访问
        filed.setAccessible(false);
        return t;
    }

    /**
     * 设定内部类-启动反射机制
     */
    static class ReflexOperation{
        /**
         * @desc 获取属性名数组
         * @param o
         * @return
         */
        public  String[] getFiledName(Object o) {
            Field[] fields = o.getClass().getDeclaredFields();
            String[] fieldNames = new String[fields.length];
            for (int i = 0; i < fields.length; i++) {
                fieldNames[i] = fields[i].getName();
            }
            return fieldNames;
        }

        /**
         * @desc 根据属性名获取属性值
         * @param fieldName
         * @param o
         * @return
         */
        public static Object getFieldValueByName(String fieldName, Object o) {
            try {
                String firstLetter = fieldName.substring(0, 1).toUpperCase();
                String getter = "get" + firstLetter + fieldName.substring(1);
                Method method = o.getClass().getMethod(getter, new Class[] {});
                Object value = method.invoke(o, new Object[] {});
                return value;
            }catch (NoSuchMethodException noSuchMethodException){
                throw new TreeException("参数名: "+fieldName+" 不存在!");
            }catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * @desc 获取属性的数据类型
         * @param fieldName
         * @param o
         * @return
         */
        public static Field getFiled(String fieldName, Object o) {
            Field[] fields = o.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (Objects.equals(fieldName, field.getName())) {
                    return field;
                }
            }
            throw new TreeException("参数名: "+fieldName+" 不存在!");
        }
    }
    /**
     * 自定义异常类
     */
   static class TreeUtilException extends Exception{
        public TreeUtilException(){

        }
        //带有详细信息的构造器,信息存储在message中
        public TreeUtilException(String message) {
            super(message);
        }
    }

    /**
     * 条件类
     */
    static class ProcessingCheck{
        static boolean isEmpty(Object object){
            if(null==object||"".equals(String.valueOf(object))){
                return true;
            }
            return false;
        }
    }

    /**
     * 测试使用
     * @param args
     */
    public static void main(String[] args) {
        List<SysMenu> list = new ArrayList<>();
        SysMenu sysMenu = new SysMenu();
        sysMenu.setMenuId("111");
        sysMenu.setPMenuId("-1");
        list.add(sysMenu);
        SysMenu sysMenu1 = new SysMenu();
        sysMenu1.setMenuId("222");
        sysMenu1.setPMenuId("-1");
        list.add(sysMenu1);
        SysMenu sysMenu2 = new SysMenu();
        sysMenu2.setMenuId("1110");
        sysMenu2.setPMenuId("111");
        list.add(sysMenu2);
        SysMenu sysMenu3 = new SysMenu();
        sysMenu3.setMenuId("2220");
        sysMenu3.setPMenuId("222");
        list.add(sysMenu3);
        SysMenu sysMenu4 = new SysMenu();
        sysMenu4.setMenuId("11101");
        sysMenu4.setPMenuId("1110");
        list.add(sysMenu4);
        SysMenu sysMenu5 = new SysMenu();
        sysMenu5.setMenuId("111010");
        sysMenu5.setPMenuId("11101");
        list.add(sysMenu5);
        SysMenu sysMenu6 = new SysMenu();
        sysMenu6.setMenuId(null);
        sysMenu6.setPMenuId(null);
        list.add(sysMenu6);
        TreeUtil<SysMenu> sysMenuTreeUtil = new TreeUtil<>();
        System.out.println(sysMenuTreeUtil.start(list,"menuId","pMenuId","childrenMnenus","-1"));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值