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;
        }
    }

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

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

  • 相关阅读:
    Nginx配置文件nginx.conf中文详解
    PHP SOCKET编程 .
    当一个变量只能通过引用传递的时候。
    PHP-Socket-阻塞与非阻塞,同步与异步概念的理解
    PHP里的socket_recv方法解释
    jQuery获取Select选择的Text和 Value
    使用 cacti 批量监控服务器以及其 PHP 运作环境配置
    windows 和 linux 上 循环读取文件名称的区别和方法
    php 在linux 用fopen() 函数打开,file_get_contents(),fread()函数 读取 另外一台服务器映射过来的文件 总是返回false,null的情况。
    【问题解决】小数点前面不显示0的问题
  • 原文地址:https://www.cnblogs.com/yanggb/p/11476879.html
Copyright © 2011-2022 走看看