list转树形结构数据工具类

本文介绍了一种将列表数据转换为树形结构的方法,通过反射机制获取对象属性,适用于不同ID字段的数据转换,实现递归构建树形结构。

方式一 

package com.zp.my_utils.util1;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * list转树形结构数据工具类可根据需求重载方法扩展)
 *
 * @author zhengpeng
 * @version 1.0
 * @create 2020/1/22 13:45
 **/
public class TreeUtils<T> {
    /**
     * 默认ID字段
     */
    private static final String DEFAULT_ID = "id";
    /**
     * 默认父级id字段
     */
    private static final String DEFAULT_PARENT_ID = "parentId";
    /**
     * 默认子级 集合字段
     */
    private static final String DEFAULT_CHILDREN = "children";
    /**
     * 顶级节点的 父级id
     */
    private static final Object TOP_PARENT_ID = null;

    /**
     * 都采用默认配置 构建树形结构
     *
     * @param list
     * @return
     */
    public static <T> List<T> createTree(List<T> list) {
        return createTree(list, DEFAULT_ID, DEFAULT_PARENT_ID, DEFAULT_CHILDREN);
    }

    /**
     * 只有 实体主键不同 构建树形结构
     *
     * @param list
     * @param idName
     * @return
     */
    public static <T> List<T> createTree(List<T> list, String idName) {
        return createTree(list, idName, DEFAULT_PARENT_ID, DEFAULT_CHILDREN);
    }

    /**
     * 构建树形结构数据
     *
     * @param list      要转换的集合
     * @param idName    实体id字段名
     * @param pIdName   实体父级id字段名
     * @param childName 实体子集集合字段名
     * @return
     */
    public static <T> List<T> createTree(List<T> list, String idName, String pIdName, String childName) {
        List<T> result = new ArrayList<T>();
        try {
            for (T t : list) {
                Class<?> aClass = t.getClass();
                Field parentId = aClass.getDeclaredField(pIdName);
                parentId.setAccessible(true);
                Object o = parentId.get(t);
                if (String.valueOf(o).equals(String.valueOf(TOP_PARENT_ID))) {
                    result.add(t);
                }
            }
            for (T parent : result) {
                recursiveTree(parent, list, idName, pIdName, childName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private static <T> T recursiveTree(T parent, List<T> list, String idName, String pIdName, String childName) throws Exception {
        List<T> children = new ArrayList<T>();
        Class<?> pClass = parent.getClass();
        Field id = pClass.getDeclaredField(idName);
        id.setAccessible(true);
        Object o = id.get(parent);
        for (T t : list) {
            Class<?> aClass = t.getClass();
            Field parentId = aClass.getDeclaredField(pIdName);
            parentId.setAccessible(true);
            Object o1 = parentId.get(t);
            if (String.valueOf(o).equals(String.valueOf(o1))) {
                t = recursiveTree(t, list, idName, pIdName, childName);
                children.add(t);
            }
        }
        Field child = pClass.getDeclaredField(childName);
        child.setAccessible(true);
        child.set(parent, children);
        return parent;
    }
}

方式二

package com.zp.my_utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * list转树形结构数据工具类(可根据需求重载方法扩展)
 *
 * @author zhengpeng
 * @version 1.0
 * @create 2020/1/22 13:45
 **/
public class TreeUtils<T> {
    /**
     * 默认ID字段
     */
    private static final String DEFAULT_ID = "id";
    /**
     * 默认父级id字段
     */
    private static final String DEFAULT_PARENT_ID = "parentId";
    /**
     * 默认子级 集合字段
     */
    private static final String DEFAULT_CHILDREN = "children";
    /**
     * 顶级节点的 父级id
     */
    private static final Object TOP_PARENT_ID = -1;

    /**
     * 获取 所有树形结构数据
     *
     * @param list 要转换的集合
     * @return
     * @throws Exception
     */
    public static <T> List<T> getChild(List<T> list) throws Exception {
        return getChild(TOP_PARENT_ID, list, DEFAULT_ID, DEFAULT_PARENT_ID, DEFAULT_CHILDREN);
    }

    /**
     * 集合转树形结构方法
     *
     * @param parentId  父级id
     * @param list      要转换的集合
     * @param idName    实体id字段名
     * @param pIdName   实体父级id字段名
     * @param childName 实体子集集合字段名
     * @return
     * @throws Exception
     */
    public static <T> List<T> getChild(Object parentId, List<T> list, String idName, String pIdName, String childName) throws Exception {
        // 子菜单
        List<T> childList = new ArrayList<T>();
        for (T t : list) {
            Class<?> aClass = t.getClass();
            Field pId = aClass.getDeclaredField(pIdName);
            pId.setAccessible(true);
            Object o = pId.get(t);
            if (o == null) {
                continue;
            }
            if (String.valueOf(o).equals(String.valueOf(parentId))) {
                childList.add(t);
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (T t : childList) {
            Class<?> aClass = t.getClass();
            Field pId = aClass.getDeclaredField(idName);
            pId.setAccessible(true);
            Object o = pId.get(t);
            List<T> childLis = getChild(String.valueOf(o), list, idName, pIdName, childName);
            Field child = aClass.getDeclaredField(childName);
            child.setAccessible(true);
            child.set(t, childLis);
        }
        // 判断递归结束
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑重其事,鹏程万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值