Hutool Hutool
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
  • 快速入门

  • 核心(hutool-core)

    • AI(Hutool-ai)

    • 注解(annotation)

    • 数组(array)

    • JavaBean(bean)

    • 缓存(cache)

    • 类加载器(classloader)

    • 编码解码(codec)

    • 集合(collection)

    • 比较器(comparator)

    • 压缩(compress)

    • 类型转换(convert)

    • 数据(data)

    • 日期时间(date)

    • 异常(exception)

    • 函数(func)

    • IO流(io)

    • 语言特性(lang)

    • Map(map)

    • 数字数学(math)

    • 网络(net)

    • 对象池(pool)

    • 反射(reflect)

    • 正则(regex)

    • 服务提供(spi)

    • 聚合操作(stream)

    • 字符串文本(text)

    • 并发和线程(thread)

    • 树结构(tree)

      • 简介
      • 树工具类-TreeUtil
      • 节点接口-Node
      • 节点解析器-NodeParser
      • 默认节点解析器-DefaultNodeParser
      • 树节点配置-TreeNodeConfig
      • Lambda节点配置-LambdaTreeNodeConfig
      • 树节点基类-TreeNode
      • 基于Map的树节点-MapTree
      • Bean树构建工具-BeanTree
      • 树构建器-TreeBuilder
        • 🎯 简介
        • 📋 核心特性
        • 🛠️ 类结构
        • 🚀 快速开始
          • 基本使用
          • 使用配置和节点转换器
        • 📖 详细方法
          • 静态工厂方法
          • of(rootId)
          • of(rootId, config)
          • 根节点配置方法
          • setId(id)
          • setParentId(parentId)
          • setName(name)
          • setWeight(weight)
          • putExtra(key, value)
          • 节点添加方法
          • append(map)
          • append(list, nodeParser)
          • append(trees)
          • append(iterator)
          • 构建方法
          • build()
          • buildList()
          • 其他方法
          • reset()
        • 🎨 使用场景
          • 1. 构建菜单树
          • 2. 构建部门树
          • 3. 构建分类树
        • 💡 注意事项
        • 🚀 性能优化
        • 🔍 最佳实践
        • 📝 总结
      • 层级迭代器-HierarchyIterator
    • 工具集合(util)

    • XML操作(xml)

  • 定时任务(hutool-cron)

  • 加密(hutool-crypto)

  • 数据库(hutool-db)

  • 扩展(hutool-extra)

  • HTTP(hutool-http)

  • 日志(hutool-log)

  • 配置文件(hutool-setting)

  • JSON(hutool-json)

  • Office办公(hutool-poi)

  • 套接字(hutool-socket)

  • GUI(hutool-swing)

  • 指南
  • 核心(hutool-core)
  • 树结构(tree)
Hutool
2026-01-03
目录

树构建器-TreeBuilder

# 🎯 简介

TreeBuilder 是 Hutool 树结构模块中的构建器类,实现了 Builder 接口,用于构建 MapTree 结构。它提供了流畅的 API 来添加节点、配置树结构,并最终生成完整的树。

# 📋 核心特性

  • ✅ 支持泛型ID,适应不同业务场景
  • ✅ 提供静态工厂方法,创建便捷
  • ✅ 支持链式调用,使用流畅
  • ✅ 支持多种节点添加方式(Map、Iterable、Iterator)
  • ✅ 支持节点转换器,灵活转换Bean为树节点
  • ✅ 支持树剪枝,限制递归深度
  • ✅ 支持构建单根树或树列表
  • ✅ 实现了Builder模式,符合设计原则
  • ✅ 支持重置复用,提高性能

# 🛠️ 类结构

typedef TreeBuilder<E>
  ├── 实现自 Builder<MapTree<E>>
  ├── 属性
  │   ├── root: MapTree<E>          // 根节点
  │   ├── idTreeMap: Map<E, MapTree<E>> // ID到节点的映射
  │   └── isBuild: boolean          // 是否已构建
  └── 方法
      ├── 静态工厂方法
      │   ├── of(rootId): TreeBuilder<T> // 创建树构建器
      │   └── of(rootId, config): TreeBuilder<T> // 创建带配置的树构建器
      ├── 构造方法
      │   ├── TreeBuilder(rootId, config) // 根据根ID和配置创建
      │   └── TreeBuilder(root) // 根据根节点创建
      ├── 根节点配置
      │   ├── setId(id): TreeBuilder<E> // 设置根节点ID
      │   ├── setParentId(parentId): TreeBuilder<E> // 设置根节点父ID
      │   ├── setName(name): TreeBuilder<E> // 设置根节点名称
      │   ├── setWeight(weight): TreeBuilder<E> // 设置根节点权重
      │   └── putExtra(key, value): TreeBuilder<E> // 向根节点添加扩展属性
      ├── 节点添加
      │   ├── append(map): TreeBuilder<E> // 添加节点Map
      │   ├── append(list, nodeParser): TreeBuilder<E> // 添加Bean列表并转换
      │   ├── append(trees): TreeBuilder<E> // 添加节点列表
      │   └── append(iterator): TreeBuilder<E> // 添加节点迭代器
      ├── 构建方法
      │   ├── build(): MapTree<E> // 构建单根树
      │   └── buildList(): List<MapTree<E>> // 构建树列表
      └── 其他方法
          └── reset(): TreeBuilder<E> // 重置构建器,支持复用

# 🚀 快速开始

# 基本使用

// 创建TreeBuilder
TreeBuilder<Long> builder = TreeBuilder.of(0L);

// 添加节点
MapTree<Long> node1 = new MapTree<>().setId(1L).setParentId(0L).setName("节点1");
MapTree<Long> node2 = new MapTree<>().setId(2L).setParentId(0L).setName("节点2");
MapTree<Long> node3 = new MapTree<>().setId(3L).setParentId(1L).setName("节点3");

// 向构建器添加节点
builder.append(List.of(node1, node2, node3));

// 构建树
MapTree<Long> tree = builder.build();

// 输出树结构
Console.log("构建的树: {}", tree);

# 使用配置和节点转换器

// 创建配置
TreeNodeConfig config = new TreeNodeConfig();
config.setNameKey("title").setChildrenKey("items");

// 定义实体类
class Menu {
    private Long id;
    private Long parentId;
    private String title;

    // 构造方法、getter和setter省略
}

// 创建菜单列表
List<Menu> menuList = new ArrayList<>();
menuList.add(new Menu(1L, 0L, "菜单1"));
menuList.add(new Menu(2L, 0L, "菜单2"));
menuList.add(new Menu(3L, 1L, "子菜单1"));

// 创建TreeBuilder并添加节点
TreeBuilder<Long> builder = TreeBuilder.of(0L, config);
builder.append(menuList, (menu, node) -> {
    node.setId(menu.getId())
        .setParentId(menu.getParentId())
        .setName(menu.getTitle());
});

// 构建树
MapTree<Long> tree = builder.build();

// 输出树结构
Console.log("菜单树: {}", tree);

# 📖 详细方法

# 静态工厂方法

# of(rootId)

  • 功能:创建树构建器

  • 参数:rootId - 根节点ID

  • 返回值:TreeBuilder<T> - 树构建器实例

  • 使用场景:快速创建树构建器,使用默认配置

  • 示例:

    TreeBuilder<Long> builder = TreeBuilder.of(0L);
    

# of(rootId, config)

  • 功能:创建带配置的树构建器

  • 参数:

    • rootId - 根节点ID
    • config - 树节点配置
  • 返回值:TreeBuilder<T> - 树构建器实例

  • 使用场景:创建带自定义配置的树构建器

  • 示例:

    TreeNodeConfig config = new TreeNodeConfig();
    config.setNameKey("label");
    TreeBuilder<Long> builder = TreeBuilder.of(0L, config);
    

# 根节点配置方法

# setId(id)

  • 功能:设置根节点ID

  • 参数:id - 根节点ID

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:修改根节点ID

  • 示例:

    builder.setId(100L);
    

# setParentId(parentId)

  • 功能:设置根节点父ID

  • 参数:parentId - 根节点父ID

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:设置根节点的父ID,通常为null或特定值

  • 示例:

    builder.setParentId(null);
    

# setName(name)

  • 功能:设置根节点名称

  • 参数:name - 根节点名称

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:设置根节点的显示名称

  • 示例:

    builder.setName("根节点");
    

# setWeight(weight)

  • 功能:设置根节点权重

  • 参数:weight - 根节点权重

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:设置根节点的排序权重

  • 示例:

    builder.setWeight(1);
    

# putExtra(key, value)

  • 功能:向根节点添加扩展属性

  • 参数:

    • key - 属性键
    • value - 属性值
  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:向根节点添加自定义属性

  • 示例:

    builder.putExtra("icon", "🏠");
    

# 节点添加方法

# append(map)

  • 功能:添加节点Map

  • 参数:map - ID到节点的映射

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:批量添加已构建的节点

  • 示例:

    Map<Long, MapTree<Long>> nodeMap = new HashMap<>();
    nodeMap.put(1L, new MapTree<Long>().setId(1L).setParentId(0L).setName("节点1"));
    builder.append(nodeMap);
    

# append(list, nodeParser)

  • 功能:添加Bean列表并转换为节点

  • 参数:

    • list - Bean列表
    • nodeParser - 节点转换器,用于将Bean转换为节点
  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:将数据库查询结果或其他Bean列表转换为树节点

  • 示例:

    builder.append(menuList, (menu, node) -> {
        node.setId(menu.getId())
            .setParentId(menu.getParentId())
            .setName(menu.getTitle())
            .setWeight(menu.getSort());
    });
    

# append(trees)

  • 功能:添加节点列表

  • 参数:trees - 节点列表

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:批量添加节点

  • 示例:

    List<MapTree<Long>> nodes = new ArrayList<>();
    nodes.add(new MapTree<Long>().setId(1L).setParentId(0L).setName("节点1"));
    nodes.add(new MapTree<Long>().setId(2L).setParentId(0L).setName("节点2"));
    builder.append(nodes);
    

# append(iterator)

  • 功能:添加节点迭代器

  • 参数:iterator - 节点迭代器

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:通过迭代器添加节点,适用于大数据量场景

  • 示例:

    Iterator<MapTree<Long>> iterator = nodeList.iterator();
    builder.append(iterator);
    

# 构建方法

# build()

  • 功能:构建单根树

  • 返回值:构建好的树的根节点

  • 使用场景:构建有明确根节点的树结构

  • 示例:

    MapTree<Long> tree = builder.build();
    

# buildList()

  • 功能:构建树列表,没有顶层节点

  • 返回值:构建好的树列表

  • 使用场景:构建多个并列的树结构

  • 示例:

    List<MapTree<Long>> treeList = builder.buildList();
    

# 其他方法

# reset()

  • 功能:重置构建器,实现复用

  • 返回值:当前构建器实例,支持链式调用

  • 使用场景:重复使用同一个构建器构建多棵树

  • 示例:

    builder.reset();
    // 重新添加节点并构建
    

# 🎨 使用场景

# 1. 构建菜单树

// 创建配置
TreeNodeConfig config = new TreeNodeConfig();
config.setNameKey("title").setChildrenKey("children").setWeightKey("sort");

// 从数据库获取菜单数据
List<Menu> menuList = menuService.findAll();

// 创建TreeBuilder
TreeBuilder<Long> builder = TreeBuilder.of(0L, config);

// 添加菜单节点
builder.append(menuList, (menu, node) -> {
    node.setId(menu.getId())
        .setParentId(menu.getParentId())
        .setName(menu.getTitle())
        .setWeight(menu.getSort())
        .putExtra("icon", menu.getIcon())
        .putExtra("url", menu.getUrl());
});

// 构建菜单树
MapTree<Long> menuTree = builder.build();

// 输出菜单树
Console.log("菜单树: {}", menuTree);

# 2. 构建部门树

// 创建TreeBuilder
TreeBuilder<Long> builder = TreeBuilder.of(0L);

// 部门数据
List<Department> deptList = departmentService.findAll();

// 添加部门节点
builder.append(deptList, (dept, node) -> {
    node.setId(dept.getId())
        .setParentId(dept.getParentId())
        .setName(dept.getDeptName())
        .setWeight(dept.getOrderNum())
        .putExtra("code", dept.getDeptCode())
        .putExtra("leader", dept.getLeaderName());
});

// 构建部门树
MapTree<Long> deptTree = builder.build();

// 输出部门树
Console.log("部门树: {}", deptTree);

# 3. 构建分类树

// 创建配置
TreeNodeConfig config = new TreeNodeConfig();
config.setDeep(2); // 限制深度为2层

// 创建TreeBuilder
TreeBuilder<String> builder = TreeBuilder.of("0", config);

// 分类数据
List<Category> categoryList = categoryService.findAll();

// 添加分类节点
builder.append(categoryList, (category, node) -> {
    node.setId(category.getCatId())
        .setParentId(category.getParentId())
        .setName(category.getCatName())
        .setWeight(category.getSortOrder())
        .putExtra("level", category.getLevel())
        .putExtra("enabled", category.getEnabled());
});

// 构建分类树
MapTree<String> categoryTree = builder.build();

// 输出分类树
Console.log("分类树: {}", categoryTree);

# 💡 注意事项

  1. 构建状态检查:

    • 一旦调用build()或buildList()方法,构建器将进入已构建状态
    • 已构建状态下不能再添加节点,需要调用reset()方法重置
    • 调用reset()会清空所有节点和构建状态
  2. 根节点处理:

    • 构建器会自动处理根节点,如果添加的节点中包含根节点ID,会复用该节点
    • 根节点的ID在创建构建器时指定,通常为0或"0"
  3. 节点转换器:

    • 节点转换器用于将Bean转换为节点,需要实现NodeParser接口
    • 转换器中可以设置节点的各种属性,包括扩展属性
  4. 树剪枝:

    • 如果配置了deep属性,构建器会自动剪枝,只保留指定深度的节点
    • 剪枝操作会在构建完成后执行
  5. 性能考虑:

    • 对于大量节点的场景,建议使用append(Iterator)方法,减少内存占用
    • 构建完成后,idTreeMap会被清空,释放内存
    • 可以使用reset()方法复用构建器,避免重复创建对象
  6. 泛型类型:

    • E是ID的类型,建议使用Long、String等不可变类型
    • 确保所有节点的ID类型一致,否则会导致类型转换错误

# 🚀 性能优化

  • 对于大数据量场景,使用Iterator方式添加节点,避免一次性加载所有数据到内存
  • 合理设置deep属性,避免构建过深的树结构
  • 复用构建器实例,使用reset()方法重置后再次使用
  • 节点转换器中避免复杂计算,提高转换效率
  • 对于固定的节点结构,考虑缓存转换结果

# 🔍 最佳实践

  1. 使用静态工厂方法:优先使用of()静态方法创建构建器,代码更简洁
  2. 链式调用:利用链式调用特性,使代码更流畅易读
  3. 节点转换器复用:对于相同类型的Bean转换,复用节点转换器实例
  4. 合理配置深度:根据业务需求设置合适的递归深度
  5. 扩展属性使用:充分利用扩展属性,存储节点的额外信息
  6. 构建后释放资源:构建完成后,构建器会自动清空中间数据,无需手动处理
  7. 异常处理:在节点转换器中添加适当的异常处理,确保构建过程稳定

# 📝 总结

TreeBuilder 是 Hutool 树结构模块中的核心构建器类,提供了灵活、高效的树构建能力。它支持多种节点添加方式,包括直接添加节点、添加节点Map、添加Bean列表并转换等。通过链式调用和Builder模式,使得树构建过程更加流畅和直观。

无论是构建简单的菜单树,还是复杂的部门树、分类树,TreeBuilder 都能提供可靠的支持。它的泛型设计和节点转换器机制,使得它能够适应各种业务场景和数据结构。

在实际开发中,建议根据具体需求选择合适的节点添加方式,并合理配置树的深度和其他属性。通过TreeBuilder,可以快速构建出符合业务需求的树结构,提高开发效率和代码质量。

Bean树构建工具-BeanTree
层级迭代器-HierarchyIterator

← Bean树构建工具-BeanTree 层级迭代器-HierarchyIterator→

Theme by Vdoing | Copyright © 2025-2026 Hutool | Apache-2.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式