首页 > 编程语言 >构建树形结构集合的方法-Java

构建树形结构集合的方法-Java

时间:2024-03-25 12:29:43浏览次数:32  
标签:node Java String TableTest list param 树形 构建 public

完整代码如下

构建树形结构方法

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

public class TableUtils<T> {

    /**
     * 集合构建成层级结构
     *
     * ps:处于顶级的数据,上下级字段值必须为空
     *
     * @param list 集合
     * @param primaryKeyName 主键字段名称
     * @param nodeName 上下级字段名称
     * @param childName 存放子集合的字段名称
     * @param splitter 分割符
     * @return 层级结构的集合
     */
    public static <T> List<T> tree(List<T> list, String primaryKeyName, String nodeName, String childName, String splitter) {
        List<T> topNode = new ArrayList<>();
        try {
            LinkedList<T> linkedList = new LinkedList<>(list);
            while (!linkedList.isEmpty()) {
                T first = linkedList.removeFirst();
                Object nodeObj = getDeclaredFieldValue(first, nodeName);
                Object primaryKeyObj = getDeclaredFieldValue(first, primaryKeyName);
                Field childFiled = getDeclaredField(first, childName);
                if (JudgeUtils.isNull(childFiled.get(first))) {
                    childFiled.set(first, new ArrayList<>());
                }
                List<T> childList = (List<T>) childFiled.get(first);
                String nodeValue = "";
                if (JudgeUtils.isNull(nodeObj)) {
                    nodeValue += primaryKeyObj;
                } else {
                    String nodeCon = (String) nodeObj;
                    String node = nodeCon.endsWith(",") ? nodeCon.substring(0, nodeCon.lastIndexOf(",")) : nodeCon;
                    nodeValue = node + splitter + primaryKeyObj;
                }
                for (T node : linkedList) {
                    Object secondNodeObj = getDeclaredFieldValue(node, nodeName);
                    String secondNodeCon = JudgeUtils.isNull(secondNodeObj) ? "" : (String) secondNodeObj;
                    String secondNode = secondNodeCon.endsWith(",") ? secondNodeCon.substring(0, secondNodeCon.lastIndexOf(",")) : secondNodeCon;
                    if (nodeValue.equals(secondNode)) {
                        childList.add(node);
                    }
                }
            }
            for (T original : list) {
                if (JudgeUtils.isNull(getDeclaredFieldValue(original, nodeName))) {
                    topNode.add(original);
                }
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }
        return topNode;
    }

    private static <T> Field getDeclaredField(T clz, String fieldName) throws NoSuchFieldException {
        Field field = clz.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field;
    }

    private static <T> Object getDeclaredFieldValue(T clz, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        return getDeclaredField(clz, fieldName).get(clz);
    }

}

用到的校验方法

import java.lang.reflect.Field;

/**
 * 检验工具类
 */
public class JudgeUtils<T> {

    /**
     * 判断字符串为空
     *
     * @param str 字符串
     */
    public static boolean isEmpty(String str) {
        return str == null || "".equals(str.trim());
    }

    /**
     * 判断对象为空
     *
     * @param o 对象
     */
    public static boolean isNull(Object o) {
        return o == null;
    }

    /**
     * 判断对象及其字段全为空
     *
     * @param o 对象
     */
    public static boolean isAllNull(Object o) {
        boolean flag = isNull(o);
        if (!flag) {
            try {
                for (Field field : o.getClass().getDeclaredFields()) {
                    field.setAccessible(true);
                    if (!isNull(field.get(o))) {
                        return false;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return flag;
    }

    /**
     * 断言-true则报错
     *
     * @param state 状态
     * @param msg 报错内容
     */
    public static void assertion(boolean state, String msg) {
        if (state) {
            throw new RuntimeException(msg);
        }
    }

    /**
     * 断言-检查对象不为空-true则报错-false则返回该对象
     *
     * @param t 对象
     * @param msg 报错内容
     */
    public static<T> T checkNotNull(T t, String msg) {
        if (t instanceof String) {
            assertion(isEmpty((String) t), msg);
        } else {
            assertion(isNull(t), msg);
        }
        return t;
    }

    /**
     * 断言-检查对象为空-true则返回该对象-false则报错
     *
     * @param t 对象
     * @param msg 报错内容
     */
    public static<T> T checkIsNull(T t, String msg) {
        if (t instanceof String) {
            assertion(!isEmpty((String) t), msg);
        } else {
            assertion(!isNull(t), msg);
        }
        return t;
    }

}

测试用例

测试表对象

import java.util.ArrayList;
import java.util.List;

public class TableTest {

    /**
     * 主键字段
     */
    private Long id;

    /**
     * 上下级字段(示例:1,3,5)
     * ps:顶级该值要为空
     */
    private String node;

    /**
     * 子集合字段
     */
    private List<TableTest> list = new ArrayList<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNode() {
        return node;
    }

    public void setNode(String node) {
        this.node = node;
    }

    public List<TableTest> getList() {
        return list;
    }

    public void setList(List<TableTest> list) {
        this.list = list;
    }

    public TableTest() {
    }

    public TableTest(Long id, String node, List<TableTest> list) {
        this.id = id;
        this.node = node;
        this.list = list;
    }

    @Override
    public String toString() {
        return "TableTest{" +
                "id=" + id +
                ", node='" + node + '\'' +
                ", list=" + list +
                '}';
    }
}

测试方法

import cn.cgj.system.domain.TableTest;
import cn.cgj.util.TableUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class UnitTest {

    @Test
    public void test() throws NoSuchFieldException, IllegalAccessException {
        TableTest tableTop1 = new TableTest(1L, null, null);
        TableTest tableTop2 = new TableTest(2L, null, null);
        TableTest tableSon1 = new TableTest(3L, "1", null);
        TableTest tableSon2 = new TableTest(4L, "2,", null);
        TableTest tableSon3 = new TableTest(5L, "1,3", null);
        TableTest tableSon4 = new TableTest(6L, "2,4,", null);

        List<TableTest> list = new ArrayList<TableTest>() {{
            add(tableTop1);
            add(tableTop2);
            add(tableSon1);
            add(tableSon2);
            add(tableSon3);
            add(tableSon4);
        }};

        List<TableTest> hierarchy = TableUtils.tree(list, "id", "node", "list", ",");
        hierarchy.forEach(System.err::print);
    }
}

标签:node,Java,String,TableTest,list,param,树形,构建,public
From: https://blog.csdn.net/2301_77191133/article/details/137010346

相关文章

  • 为什么使用类型化数组来进行字节操作而不是普通的 javascript 数字数组
    1.javascript中的数字数据类型默认为64位(8字节),无论任何数字。这意味着可以在不损失精度的情况下表示-2⁵³+1到2⁵³–1范围内的数字。这意味着即使我们想存储10个,也会消耗8个字节的内存,而这是根本不需要的。当内存效率是一个问题时,特别是在处理大型整数数组或二进制数......
  • java毕业设计体育r品在线销售系统(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的飞速发展和电子商务的普及,人们的购物方式正逐渐从传统的实体店转向在线购物平台。体育用品市场作为一个具有庞大消费群体和持续增长潜力......
  • java毕业设计网上生鲜超市(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的不断进步和人们生活节奏的加快,传统的购物模式已经无法完全满足现代社会的需求。特别是在生鲜食品领域,消费者对新鲜、健康、快捷的要求越......
  • java se 基础
    javase基础前言:补一些java基础知识前置知识在写java的基础知识前,我们先来学习一下用vscode运行java项目的一些基础内容,首先,想要在vscode中运行java在下载插件后需要创建java项目,一个不用其余工具的java项目中有两个文件夹,一个是lib,用于存储引用的包,一个是src,用于存储源代......
  • 一文让你读懂JavaScript原型对象与原型链的继承
    前言有些新手朋友可能听说过这么一句话,就是js中存在两个链条,它们分别为:作用域链和原型链它们彼此的区别在于作用域链是为了访问变量和数据而存在的一种链条访问机制而原型链是访问对象的属性或者方法而存在的一种机制!其中这里的原型链就是今天我要说的主题!我们学习js必须......
  • 用生动的语言讲mysql索引机制与B+树形象化理解
    索引,index,是什么呢,假如说,没有索引,比如你要点名,你就得挨个问,你是不是某某某,效率奇低,但是,当他们有了独一无二的号数或者名字,就可以免于追寻,一觅即中,这就是索引存在的意义但是,凡事有利有弊,索引增加了查询的效率,但是却降低了增删改的效率,比如说,班级加入一名新同学,你还要给他一个号数,......
  • JavaScript:void(0) 用法及常见问题解析
    JavaScript:void(0)用法及常见问题解析javascript:void(0);是一种在JavaScript和网页开发中经常使用的技术,尤其在处理链接的行为时。本文将深入探讨javascript:void(0);的用法,以及在使用过程中可能遇到的常见问题和解决方法。什么是javascript:void(0);?javascript:v......
  • JAVA----基础篇
    java基础1.JDKJDK:javadevelopmentkitJRE:javaruntimeenvironmentJDK包含JREjava跨平台:因为java程序运行依赖虚拟机,虚拟机需要有对应操作系统的版本,而jre中有虚拟机。当你想要在Linux系统下运行,则需要安装对应的虚拟机,及对应的jdk版本,而对应的jdk版本中的jre有对......
  • 阿里二面:Java中锁的分类有哪些?你能说全吗?
    引言在多线程并发编程场景中,锁作为一种至关重要的同步工具,承担着协调多个线程对共享资源访问秩序的任务。其核心作用在于确保在特定时间段内,仅有一个线程能够对资源进行访问或修改操作,从而有效地保护数据的完整性和一致性。锁作为一种底层的安全构件,有力地防止了竞态条件和数据不......
  • Ftrans安全数据摆渡系统 构建便捷的内外网数据交换通道!
    安全数据摆渡系统是一种设计用于解决内外网环境下,数据传输、管理、共享问题的安全系统,通过加密、访问控制等策略,提供安全可靠的数据传输和共享服务,尤其适用于对网络安全建设要求高的行业,比如研发型企业、党政机构、金融等等。安全数据摆渡系统可以解决以下问题:1、数据安全性:通......