zoukankan      html  css  js  c++  java
  • java构建树形列表(带children属性)

    一些前端框架提供的树形表格需要手动构建树形列表(带children属性的对象数组),这种结构一般是需要在Java后台构建好。

    构建的方式是通过id字段与父id字段做关联,通过递归构建children字段来达到构建树形列表的目的。

    /**
     * 树形表格工具类
     *
     * @author yanggb
     */
    public class TreeTableUtil {/**
         * 把列表转换为树结构
         *
         * @param originalList      原始list数据
         * @param idFieldName       作为唯一标示的字段名称
         * @param pidFieldName      父节点标识字段名
         * @param childrenFieldName 子节点(列表)标识字段名
         * @return 树结构列表
         */
        public static <T> List<T> list2TreeList(List<T> originalList, String idFieldName, String pidFieldName,
                                                String childrenFieldName) {
            // 获取根节点,即找出父节点为空的对象
            List<T> rootNodeList = new ArrayList<>();
            for (T t : originalList) {
                String parentId = null;
                try {
                    parentId = BeanUtils.getProperty(t, pidFieldName);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                }
                if (StringUtils.isBlank(parentId)) {
                    rootNodeList.add(0, t);
                }
            }
    
            // 将根节点从原始list移除,减少下次处理数据
            originalList.removeAll(rootNodeList);
    
            // 递归封装树
            try {
                packTree(rootNodeList, originalList, idFieldName, pidFieldName, childrenFieldName);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return rootNodeList;
        }
    
        /**
         * 封装树(向下递归)
         *
         * @param parentNodeList    要封装为树的父节点对象集合
         * @param originalList      原始list数据
         * @param keyName           作为唯一标示的字段名称
         * @param pidFieldName      父节点标识字段名
         * @param childrenFieldName 子节点(列表)标识字段名
         */
        private static <T> void packTree(List<T> parentNodeList, List<T> originalList, String keyName,
                                         String pidFieldName, String childrenFieldName) throws Exception {
            for (T parentNode : parentNodeList) {
                // 找到当前父节点的子节点列表
                List<T> children = packChildren(parentNode, originalList, keyName, pidFieldName, childrenFieldName);
                if (children.isEmpty()) {
                    continue;
                }
    
                // 将当前父节点的子节点从原始list移除,减少下次处理数据
                originalList.removeAll(children);
    
                // 开始下次递归
                packTree(children, originalList, keyName, pidFieldName, childrenFieldName);
            }
        }
    
        /**
         * 封装子对象
         *
         * @param parentNode        父节点对象
         * @param originalList      原始list数据
         * @param keyName           作为唯一标示的字段名称
         * @param pidFieldName      父节点标识字段名
         * @param childrenFieldName 子节点(列表)标识字段名
         */
        private static <T> List<T> packChildren(T parentNode, List<T> originalList, String keyName, String pidFieldName,
                                                String childrenFieldName) throws Exception {
            // 找到当前父节点下的子节点列表
            List<T> childNodeList = new ArrayList<>();
            String parentId = BeanUtils.getProperty(parentNode, keyName);
            for (T t : originalList) {
                String childNodeParentId = BeanUtils.getProperty(t, pidFieldName);
                if (parentId.equals(childNodeParentId)) {
                    childNodeList.add(t);
                }
            }
    
            // 将当前父节点下的子节点列表写入到当前父节点下(给子节点列表字段赋值)
            if (!childNodeList.isEmpty()) {
                FieldUtils.writeDeclaredField(parentNode, childrenFieldName, childNodeList, true);
            }
    
            return childNodeList;
        }
    }

    直接上代码就好了,我相信秃头的你一定能看得懂。

    "这个世界并不在乎你的自尊,只在乎你做出来的成绩,然后再去强调你的感受。"

  • 相关阅读:
    快速排序
    Java LinkedList
    Java ArrayList
    Java ReentrantLock
    Java Timer
    Java 管道PipedInputStream PipedOutStream PipedReader PipedWriter
    6. Samba服务和防火墙配置笔记
    5. 网络配置与FTP服务笔记
    3.vi 和软件安装
    2 . Linux常见命令
  • 原文地址:https://www.cnblogs.com/yanggb/p/11476879.html
Copyright © 2011-2022 走看看