一些前端框架提供的树形表格需要手动构建树形列表(带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构建树形列表(带children属性)的更多相关文章

  1. java构建树形菜单递归工具类

    1.设计菜单实体 import java.util.List; public class Menu { //菜单id private Long id; //父节点id private Long par ...

  2. Winform开发主界面菜单的动态树形列表展示

    我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一 ...

  3. 数据库中树形列表(以easyui的tree为例)

    构造一棵easyui前台框架的一个树形列表为例后台框架是spring MVC+JPA. 先看一下数据库是怎么建的,怎么存放的数据 下面是实体类 /** * 部门类 用户所属部门(这里的部门是一个相对抽 ...

  4. 转:最近5年133个Java面试问题列表

    最近5年133个Java面试问题列表 Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来 ...

  5. 近5年133个Java面试问题列表

    Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入. 在我 ...

  6. Gradle 笔记——Java构建入门

    Gradle是一个通用的构建工具,通过它的构建脚本你可以构建任何你想要实现的东西,不过前提是你需要先写好构建脚本的代码.而大部分的项目,它们的构建流程基本是一样的,我们不必为每一个工程都编写它的构建代 ...

  7. 如何将数据库中存的树转化为树形列表(以easyui的tree为例)

    很多时候,我们会把一棵树存放到数据库中,当前台需要展示一个树形列表时,将这棵树读取出来并显示,这个过程是怎么实现的呢? 这篇文章是以构造一棵easyui前台框架的一个树形列表为例,后台框架是sprin ...

  8. 在Bootstrap开发框架中使用bootstrapTable表格插件和jstree树形列表插件时候,对树列表条件和查询条件的处理

    在我Boostrap框架中,很多地方需要使用bootstrapTable表格插件和jstree树形列表插件来共同构建一个比较常见的查询界面,bootstrapTable表格插件主要用来实现数据的分页和 ...

  9. 最近5年183个Java面试问题列表及答案[最全]

    Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别(String 类型和 StringBuffer 类型的主要性能区别其实在于 Stri ...

随机推荐

  1. What is Java virtual machine?

    Java Virtual Machine (JVM) is a specification that provides runtime environment in which java  bytec ...

  2. C#将Excel数据表导入SQL数据库的两种方法

    最近用写个winform程序想用excel 文件导入数据库中,网上寻求办法,找到了这个经过尝试可以使用. 方法一: 实现在c#中可高效的将excel数据导入到sqlserver数据库中,很多人通过循环 ...

  3. 创建WPF项目

    参考: https://www.cnblogs.com/yhcao/p/6237611.html https://mahapps.com/guides/reporting-issues.html ht ...

  4. CentOS安装Docker-ce并配置中国国内加速(aliyun)镜像

    前提条件 1.系统.内核 CentOS7 要求64位系统.内核版本3.10以上 CentOS6 要求版本在6.5以上,系统64位.内核版本2.6.32-431以上 查看内核版本号 uname -r # ...

  5. .net ajax跨域请求问题

    </system.codedom>     <system.webServer>         <defaultDocument>             < ...

  6. Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的特点

    1.不变性 新的日期/时间API中,所有的类都是不可变的,这对多线程环境有好处. 比如:LocalDateTime 2.关注点分离 新的API将人可读的日期时间和机器时间(unix timestamp ...

  7. postgreSQL数据库的初探

    kali是黑客的强大武器,还有一个也是哦——Metasploit postgreSQL数据库是Metasploit的默认数据库哦! 启动postgresql: service postgresql s ...

  8. Python的包package的导入与被导入(包的类和方法的导入,__init__()怎么写)

    包package的导入与被导入: 参考一下: https://blog.csdn.net/guowujun321/article/details/80764468 1.文件目录: | |--  A/ ...

  9. rust 高级话题

    目录 rust高级话题 前言 零大小类型ZST 动态大小类型DST 正确的安装方法 结构体 复制和移动 特征对象 引用.生命周期.所有权 生命周期 错误处理 交叉编译 智能指针 闭包 动态分派和静态分 ...

  10. Saltstack_使用指南08_远程执行-返回程序

    1. 主机规划 salt 版本 [root@salt100 ~]# salt --version salt (Oxygen) [root@salt100 ~]# salt-minion --versi ...