Hutool 使用TreeUtil工具解决树形结构

本文介绍了一种将普通列表转换成树形结构的方法,并通过具体示例演示了如何使用Hutool库中的TreeUtil工具类完成这一过程。此外,还提供了一个自定义工具类来获取实体类的字段名。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树形结构代码来源:https://blog.youkuaiyun.com/Anenan/article/details/113029547

工具类代码来源:https://www.cnblogs.com/liangweiping/archive/2020/04/28/12792418.html

  1. pom.xml的依赖
        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.2.4</version>
        </dependency>
  1. TreeNodeConfig的默认配置
    在这里插入图片描述

  2. 测试用例

    public static void main(String[] args) {
        class City {
            private Integer id;
            private String cityName;
            private Integer parentId;
            private List<City> children;
            
            //省略get,set
            
            public City(Integer id, String cityName, Integer parentId) {
                this.id = id;
                this.cityName = cityName;
                this.parentId = parentId;
            }
        }
        List<City> cities = CollUtil.newArrayList();
        cities.add(new City(1, "广东省", 0));
        cities.add(new City(2, "广州市", 1));
        cities.add(new City(3, "南沙区", 2));
        cities.add(new City(4, "万顷沙镇", 3));
        cities.add(new City(5, "黄阁镇", 3));
        cities.add(new City(6, "湖南省", 0));
        cities.add(new City(7, "长沙市", 6));
        cities.add(new City(8, "芙蓉区", 7));
        // 2.配置
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey(ColumnUtil.getName(City::getId));
        //默认为id可以不设置
        //config.setIdKey("id");
        //默认为parentId可以不设置
        //config.setParentIdKey("parentId");
        //最大递归深度
        //config.setDeep(2);
        //默认为children不用设置
        //config.setChildrenKey("children");
        // 3.转树,Tree<>里面泛型为id的类型
        List<Tree<Integer>> build = TreeUtil.build(cities, 0, config, (object, tree) -> {
            // 也可以使用 tree.setId(object.getId());等一些默认值
            Field[] fields = ReflectUtil.getFieldsDirectly(object.getClass(), true);
            for (Field field : fields) {
                String fieldName = field.getName();
                Object fieldValue = ReflectUtil.getFieldValue(object, field);
                tree.putExtra(fieldName, fieldValue);
            }
            //如果不想全部字段可以按照下面的写法添加
            /*tree.putExtra("id", object.getId());
            tree.putExtra("parentId", object.getParentId());
            tree.putExtra("cityName", object.getCityName());*/
        });
        System.out.println(JSON.toJSON(build));
    }
  1. 推荐一个工具类给大家
/**
 * 使Function获取序列化能力
 *
 * @author GideonYeung
 * @date 2020/11/30 9:02
 */
@FunctionalInterface
public interface SerializableFunction<T, R> extends Function<T, R>, Serializable {
}
/**
 * 获取某个实体类的字段名称
 *
 * @author GideonYeung
 * @date 2020/11/30 9:03
 */
public class ColumnUtil {

    public static <T> String getName(SerializableFunction<T, ?> fn) {
        // 从function取出序列化方法
        Method writeReplaceMethod;
        try {
            writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isAccessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda;
        try {
            serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        writeReplaceMethod.setAccessible(isAccessible);

        // 从lambda信息取出method、field、class等
        String fieldName = serializedLambda.getImplMethodName().substring("get".length());
        fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());

        return fieldName;
    }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值