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

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

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

原文地址:https://www.cnblogs.com/yanggb/p/11476879.html

时间: 2024-11-05 18:48:44

java构建树形列表(带children属性)的相关文章

java构建树形节点优化

引言:java中构建树形节点时,数据量小的话,可以随便些 ,不影响,但是当数据量大了以后,一棵大大的树,要半天才出来,所以就想着优化一下. 树形节点数据构建: package me.zhengjie; import ch.qos.logback.classic.joran.action.RootLoggerAction; import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; import lombok.Data;

Java构建树形菜单

构建树形菜单 效果图:支持多级菜单. 菜单实体类: public class Menu { // 菜单id private String id; // 菜单名称 private String name; // 父菜单id private String parentId; // 菜单url private String url; // 菜单图标 private String icon; // 菜单顺序 private int order; // 子菜单 private List<Menu> ch

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

我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一二级菜单,这种方式在一般功能点不算太多的情况下,呈现的界面效果较为直观.也较为美观.不过随着一些系统功能的增多,这种方式可能就会显得工具栏比较拥挤,那么我们是否可以在左侧放置一个树形列表,这样通过树形列表的收缩折叠,就可以放置非常多的菜单功能了. 1.菜单的树形列表展示 一般情况下,树形列表的显示可

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

最近5年133个Java面试问题列表 Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入. 在我初入职场的时候,类似于 Vector 与 Array 的区别.HashMap 与 Hashtable 的区别是最流行的问题,只需要记住它们,就能在面试中获得更好的机会,但这种情形已经不复存在.如今,你将会被问到许多 Java 程序员都没有看过的领域,如 NIO,

Ajax-ajax实例3-动态树形列表

项目结构: 项目演示: 技术要点: 1.3.2 技术要点在基本原理的介绍中,了解到通过在父节点内动态创建子节点,并利用样式表缩进完成树形列表的基本框架.除了这一点外,还有下面一些问题需要考虑.1 .将父节点所有的子节点放入一个容器中基本原理页面中仅包含了创建子节点的功能,不可以将创建好的节点再进行关闭操作.实际应用中菜单总是包含打开和关闭两种操作.为了方便进行关闭操作,将子节点放入一个容器中,在关闭时只需要设置容器的显示属性即可.2 .节点开关的具体实现每个父节点的所有子节点放入容器中后,在单击

Gradle 笔记——Java构建入门

Gradle是一个通用的构建工具,通过它的构建脚本你可以构建任何你想要实现的东西,不过前提是你需要先写好构建脚本的代码.而大部分的项目,它们的构建流程基本是一样的,我们不必为每一个工程都编写它的构建代码,因为Gradle已经为我们提供了相应的插件.Gradle 本身自带了许多插件,而对于Gradle没有的插件,可以去github上看看有没有其他人实现,或自己实现.对Java项目而言,Gradle有Java插件,提供了像编译.测试.打包之类的功能. 这里简单介绍一下Java插件. Java插件为构

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

很多时候,我们会把一棵树存放到数据库中,当前台需要展示一个树形列表时,将这棵树读取出来并显示,这个过程是怎么实现的呢? 这篇文章是以构造一棵easyui前台框架的一个树形列表为例,后台框架是spring MVC+JPA. 首先看一下数据库中这颗树是怎么存的: 树的结构一目了然,这是一棵表示部门的树. 下面是实体类: /** * 部门类 用户所属部门(这里的部门是一个相对抽象的词) * 使用前缀编码,每级增加三个数字,如:第一级 001,第二级001001,第三级001001001 * @auth

java面向对象周测带答案

java面向对象周测带答案 一.简答题(每题5分,共计40分)1.什么是类?什么是对象?类与对象的关系是什么? 类本质上就是分类的意思,也就是具有相同共性的一类事物的抽象描述.类就是一种用户可以自定义的引用数据类型,用于包装描述属性的成员变量,和用于描述行为的成员方法,换句话说,类可以用于描述多个不同类型的数据.类是一种抽象的概念,用于描述对象创建的模板,而对象是客观存在的实体,本质上就是内存空间中的一块区域,对象的数据结构取决于类. 2.请写出类.属性.行为的定义格式,以及引用和对象的定义格式

利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils

有时遇到将数据传输对象转换成JSON串会将属性值为空的属性去掉,利用Java反射实现JavaBean对象数据传输对象的相同属性复制并初始化数据传输对象属性为空的属性,然后转换成JSON串 package com.banksteel.util; import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Arrays;import java.ut