Java接口常见场景:返回树形结构

一、背景

在日常开发过程中,树形结构是一种非常常见的数据结构。它由节点组成,每个节点可以有多个子节点。这种结构在许多应用场景中都非常有用,例如文件系统、数据库索引、组织架构等。在Java中,我们可以使用类和方法来表示树形结构,并实现对其进行操作的方法。

二、代码示例

2.1 通用树形BaseTree类

下面的通用类只是一个示例,大家可以根据自己项目的需求进行调整,比如id是Long类型的等等。

java 复制代码
/**
 * <p>Description: 统一树结构</p>
 */
@Data
@ApiModel(description = "统一树结构")
public class BaseTree<T> {

    @ApiModelProperty("主键")
    private String id;

    @ApiModelProperty("父节点id")
    private String parentId;

    @ApiModelProperty("层级")
    private Integer tier;

    @ApiModelProperty("子节点")
    private List<T> children = CollUtil.newArrayList(); 
}
2.2 实际返回VO

这里面的内容也可以根据自己实际要返回的数据,进行修改调整,下面只是一个示例:

java 复制代码
/**
 * <p>类型返回VO</p>
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(description = "<p>类型返回VO对象</p>")
public class TypeVO extends BaseTree<TypeVO> {

    @ApiModelProperty(value = "类别编码")
    private String code;

    @ApiModelProperty(value = "类别名称")
    private String name;
}
2.3 树形处理TreeUtils工具类

逻辑也都很清晰,主要传入一个集合列表,然后找到parentId不为空,或者传入就有parentId,将其设置为层级为1的主节点,然后通过主节点依次往下查找子节点,构建子树里面采用了递归的方式进行处理。

java 复制代码
public class TreeUtils {

    /**
     * 构建树(必须是有序的列表)
     */
    public static <T extends BaseTree> List<T> buildTree(List<T> treeNodes, String root) {
        List<T> trees = CollUtil.newArrayList();
        for (T treeNode : treeNodes) {
            if (CharSequenceUtil.isBlank(treeNode.getParentId()) || (ObjectUtil.isNotNull(root) && root.equals(treeNode.getParentId()))) {
                // 遍历的数据为一级
                treeNode.setTier(1);
                trees.add(treeNode);
                setChildrenTier(treeNode, treeNodes, 2); // 设置子节点的tier,从第二层开始,初始tier为2
            }
        }
        return trees;
    }

    /**
     * 构建子树
     */
    private static <T extends BaseTree> void setChildrenTier(T parentNode, List<T> treeNodes, int tier) {
        for (T it : treeNodes) {
            if (CharSequenceUtil.isNotBlank(it.getParentId()) && it.getParentId().equals(parentNode.getId())) {
                if (ObjectUtil.isNull(it.getChildren())) {
                    it.setChildren(CollUtil.newArrayList());
                }
                it.setTier(tier); // 设置节点的tier
                parentNode.getChildren().add(it);
                setChildrenTier(it, treeNodes, tier + 1); // 递归调用设置子节点的tier,tier加1
            }
        }
    }
}
2.4 测试结果

下面列举了一个非常建议的测试案例,首先从数据库里面查询出所有的type的数据,然后调用我们上面写好的TreeUtils进行处理,代码如下所示:

java 复制代码
   @Override
    public List<TypeVO> listAllTypesTrees() {
        List<TypeVO> typeList = typebaseMapper.selectTypes();
        return TreeUtils.buildTree(typeList, null);
    }

调用结果json:

json 复制代码
{
    "message": "操作成功",
    "code": "0",
    "data": [
        {
            "id": "4a7af8949d606024ee37acf3a578b96e",
            "parentId": null,
            "tier": 1,
            "children": [
                {
                    "id": "29486803c75db91ea90722ea7db582ce",
                    "parentId": "4a7af8949d606024ee37acf3a578b96e",
                    "tier": 2,
                    "children": [],
                    "code": "11",
                    "name": "type1-1",
                },
                {
                    "id": "406727615a6c2859d1ca8f3a4f80069a",
                    "parentId": "4a7af8949d606024ee37acf3a578b96e",
                    "tier": 2,
                    "children": [],
                    "code": "12",
                    "name": "type1-2"
                }
            ],
            "code": "1",
            "name": "type1"
        },
        {
            "id": "9eed152b4e20ff10e76b33f5dd8cc4d2",
            "parentId": null,
            "tier": 1,
            "children": [],
            "code": "2",
            "name": "type2"
        },
        {
            "id": "d1fcdbf4da384bf454aa14276cee25b1",
            "parentId": null,
            "tier": 1,
            "children": [],
            "code": "3",
            "name": "type3"
        }
    ]
}

三、总结

Java接口返回树形结构的方式主要有以下几种:1. 使用嵌套的List ;2. 使用递归方法;3. 使用JSON格式的数据。这些方式的优势在于可以方便地表示和处理具有层级关系的数据,使得代码更加简洁、易读。同时,通过接口返回树形结构,可以实现数据的动态加载,提高系统的性能。此外,使用JSON格式的数据还可以方便地进行跨平台的数据交换和解析。总之,Java接口返回树形结构的方式在处理复杂数据结构时具有很大的优势,有助于提高代码的可维护性和扩展性。

相关推荐
量化分析码农5 分钟前
股票历史数据的复权参数对照:多级别返回的字段与数值差异
java·javascript·后端
猫猫不是喵喵.15 分钟前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
瑞雪兆丰年兮25 分钟前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
曲径海盗35 分钟前
Try-Except怎么用,3个追问解答在自动化下的应用
java·jvm·oracle
Cosolar2 小时前
极简智库:快速搭建你的开源项目教程阅读平台,让 docs/ 目录被更多人看见
java·架构·github
nice_lcj5202 小时前
【从零理解 Spring AI · 16】Agent 与工作流:什么该写死,什么该让模型决定
java·人工智能·后端·spring ai·ai应用开发
北京云帆互联科技2 小时前
云帆培训考试系统更新说明:v9.3.0
java·学习
学长毕设3 小时前
基于SpringBoot的景点管理系统-附源码
java·spring boot·后端
sxlishaobin4 小时前
Maven Setting详解
java·学习·maven
知守观4 小时前
一个方法两个触发口:反编译 XXL-Job 后,我看清了 inner/job 子包的裸奔现状
java·spring boot·微服务