相关文章推荐
儒雅的饺子  ·  Idea ...·  1 月前    · 
温文尔雅的皮蛋  ·  Excel 横向导出 ...·  2 年前    · 
含蓄的山楂  ·  我的第一个 Rust Web ...·  2 年前    · 

Java利用递归实现树形结构的工具类

作者:zyqok

有时候,我们的数据是带有层级的,比如常见的省市区三级联动,就是一层套着一层。而我们在数据库存放数据的时候,往往是列表形式的,这个时候可能就需要递归处理为树形结构了。本文就为大家介绍了Java利用递归实现树形结构的工具类,希望对大家有所帮助

有时候,我们的数据是带有层级的,比如常见的省市区三级联动,就是一层套着一层,如下图:

而我们在数据库存放数据的时候,往往是列表形式的,如下图:

那么当我们从数据库查询出来,返回给前端的时候,前端又需要给出树形层级的时候,这个时候可能就需要递归处理为树形结构了,因此下面这个工具或许就可以用得上了。

我们按照上面定义一个Place对象,打上工具注解:

  • @TreeKey 标识唯一
  • @TreeParentKey 标识父节点标识
  • @TreeChildren 标识子孙节点集合
@Data
@Data
public class Place {
    @TreeKey
    private String id;
    @TreeParentKey
    private String parentId;
    private String name;
    @TreeChildren
    private List<Place> children;
    public Place(String id, String name, String parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
public class Test {
    public static void main(String[] args) {
        List<Place> places = new ArrayList<>();
        places.add(new Place("510000", "四川省", "0"));
        places.add(new Place("510100", "成都市", "510000"));
        places.add(new Place("510107", "武侯区", "510100"));
        places.add(new Place("510116", "双流区", "510100"));
        places.add(new Place("511600", "广安市", "510000"));
        places.add(new Place("511603", "前锋区", "511600"));
        places.add(new Place("511621", "岳池县", "511600"));
        List<Place> treeList = TreeUtils.getTree(places, "0");
        System.out.println(JSON.toJSONString(treeList));

最终效果:

@TreeKey

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TreeKey {

@TreeParentKey

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TreeParentKey {

@TreeChildren

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TreeChildren {

@TreeUtils

package com.csd.utils.tree;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
 * 递归求树形工具类
 * @author Yuanqiang.Zhang
 * @since 2023/3/8
public class TreeUtils {
     * 集合转化为树形
     * @param list             集合
     * @param highestParentKey 最高层父节点值
     * @param <T>              泛型
     * @return 树形
    public static <T> List<T> getTree(List<T> list, Object highestParentKey) {
        if (Objects.isNull(list) || list.isEmpty()) {
            return Collections.emptyList();
        Field key = null;
        Field parentKey = null;
        Field children = null;
        Field[] fields = list.get(0).getClass().getDeclaredFields();
        for (Field field : fields) {
            if (Objects.isNull(key)) {
                TreeKey treeKey = field.getAnnotation(TreeKey.class);
                if (Objects.nonNull(treeKey)) {
                    key = field;
                    continue;
            if (Objects.isNull(parentKey)) {
                TreeParentKey treeParentKey = field.getAnnotation(TreeParentKey.class);
                if (Objects.nonNull(treeParentKey)) {
                    parentKey = field;
                    continue;
            if (Objects.isNull(children)) {
                TreeChildren treeChildren = field.getAnnotation(TreeChildren.class);
                if (Objects.nonNull(treeChildren)) {
                    children = field;
                    continue;
        if (Objects.isNull(key) || Objects.isNull(parentKey) || Objects.isNull(children)) {
            return Collections.emptyList();
        key.setAccessible(true);
        parentKey.setAccessible(true);
        children.setAccessible(true);
        // 获取最高层数据
        List<T> highs = new ArrayList<>();
        try {
            for (T t : list) {
                Object pk = parentKey.get(t);
                if (getString(pk).equals(getString(highestParentKey))) {
                    highs.add(t);
            // 获取最高层子孙节点
            for (T t : highs) {
                setChildren(list, t, key, parentKey, children);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        return highs;
     * 获取子孙节点
     * @param list      集合
     * @param parent    父节点对象
     * @param key       唯一属性
     * @param parentKey 父唯一属性
     * @param children  节点
     * @param <T>       泛型
     * @return 带有子孙集合的父节点对象
     * @throws IllegalAccessException
    private static <T> T setChildren(List<T> list, T parent, Field key, Field parentKey, Field children) throws IllegalAccessException {
        Object k = key.get(parent);
        List<T> tempList = new ArrayList<>();
        for (T t : list) {
            Object pk = parentKey.get(t);
            if (getString(k).equals(getString(pk))) {
                tempList.add(setChildren(list, t, key, parentKey, children));
        children.set(parent, tempList);
        return parent;
     * 获取字符串
     * @param o 值
     * @return 字符串
    private static String getString(Object o) {
        return Objects.isNull(o) ? "" : o.toString();

以上就是Java利用递归实现树形结构的工具类的详细内容,更多关于Java树形结构的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
  • profiles.active多环境开发、测试、部署过程
    profiles.active多环境开发、测试、部署过程
    2023-03-03
  • 一文带你搞懂Java中线程的创建方式
    一文带你搞懂Java中线程的创建方式
    2023-03-03
  • 宁可用Lombok也不把成员设置为public原理解析
    宁可用Lombok也不把成员设置为public原理解析
    2023-03-03
  • Maven项目修改JDK版本全过程
    Maven项目修改JDK版本全过程
    2023-03-03
  • 怎样通过反射获取非静态内部类实例
    怎样通过反射获取非静态内部类实例
    2023-03-03
  • Java利用递归实现树形结构的工具类
    Java利用递归实现树形结构的工具类
    2023-03-03
  • Java平台调试体系原理分析和实践整理 远程Debug
    Java平台调试体系原理分析和实践整理 远程Debug
    2023-03-03
  • SpringBoot 将配置文件挂到 jar 包外面的操作方法
    SpringBoot 将配置文件挂到 jar 包外面的操作方法
    2023-03-03
  • 美国设下计谋,用娘炮文化重塑日本,已影响至中国
    美国设下计谋,用娘炮文化重塑日本,已影响至中国
    2021-11-19
  • 时空伴随者是什么意思?时空伴随者介绍
    时空伴随者是什么意思?时空伴随者介绍
    2021-11-09
  • 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终
    2021-11-05
  • 2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2022年放假安排出炉:五一连休5天 2022年所有节日一览表
    2021-10-26
  • 电脑版 - 返回首页

    2006-2023 脚本之家 JB51.Net , All Rights Reserved.
    苏ICP备14036222号