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
        • 🎯 简介
        • 📋 核心特性
        • 🛠️ 类结构
        • 🚀 快速开始
          • 基本使用
          • 混合使用Lambda和字符串配置
        • 📖 详细方法
          • Lambda函数配置
          • getIdKeyFun()
          • setIdKeyFun(idKeyFun)
          • getParentIdKeyFun()
          • setParentIdKeyFun(parentIdKeyFun)
          • getWeightKeyFun()
          • setWeightKeyFun(weightKeyFun)
          • getNameKeyFun()
          • setNameKeyFun(nameKeyFun)
          • getChildrenKeyFun()
          • setChildrenKeyFun(childrenKeyFun)
          • 重写的父类方法
          • getIdKey()
          • getParentIdKey()
          • getWeightKey()
          • getNameKey()
          • getChildrenKey()
        • 🎨 使用场景
          • 1. 实体类树构建
          • 2. 动态字段配置
          • 3. 结合BeanTree使用
        • 💡 注意事项
        • 🚀 性能优化
        • 🔍 最佳实践
        • 📝 总结
      • 树节点基类-TreeNode
      • 基于Map的树节点-MapTree
      • Bean树构建工具-BeanTree
      • 树构建器-TreeBuilder
      • 层级迭代器-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
目录

Lambda节点配置-LambdaTreeNodeConfig

# 🎯 简介

LambdaTreeNodeConfig 是 TreeNodeConfig 的子类,它引入了 Lambda 表达式支持,允许使用方法引用而非硬编码字符串来配置树节点的各种属性。这种方式可以避免因字段名变更导致的运行时错误,提高代码的类型安全性和可维护性。

# 📋 核心特性

  • ✅ 继承自 TreeNodeConfig,保留所有原有功能
  • ✅ 支持使用 Lambda 表达式配置节点属性
  • ✅ 支持方法引用,避免硬编码字段名
  • ✅ 类型安全,编译时检查字段是否存在
  • ✅ 支持链式调用
  • ✅ 自动兼容原有字符串配置
  • ✅ 实现了序列化接口

# 🛠️ 类结构

typedef LambdaTreeNodeConfig<T, R>
  ├── 继承自 TreeNodeConfig
  ├── 泛型参数
  │   ├── T: 方法对象类型
  │   └── R: 返回值类型
  ├── 属性
  │   ├── idKeyFun: SerFunction<T, R>                // ID字段Lambda函数
  │   ├── parentIdKeyFun: SerFunction<T, R>          // 父节点ID字段Lambda函数
  │   ├── weightKeyFun: SerFunction<T, Comparable<?>> // 权重字段Lambda函数
  │   ├── nameKeyFun: SerFunction<T, CharSequence>    // 名称字段Lambda函数
  │   └── childrenKeyFun: SerFunction<T, List<T>>     // 子节点字段Lambda函数
  └── 方法
      ├── getIdKeyFun(): SerFunction<T, R>          // 获取ID字段Lambda函数
      ├── setIdKeyFun(idKeyFun): LambdaTreeNodeConfig<T, R> // 设置ID字段Lambda函数(链式)
      ├── getParentIdKeyFun(): SerFunction<T, R>    // 获取父节点ID字段Lambda函数
      ├── setParentIdKeyFun(parentIdKeyFun): LambdaTreeNodeConfig<T, R> // 设置父节点ID字段Lambda函数(链式)
      ├── getWeightKeyFun(): SerFunction<T, Comparable<?>> // 获取权重字段Lambda函数
      ├── setWeightKeyFun(weightKeyFun): LambdaTreeNodeConfig<T, R> // 设置权重字段Lambda函数(链式)
      ├── getNameKeyFun(): SerFunction<T, CharSequence> // 获取名称字段Lambda函数
      ├── setNameKeyFun(nameKeyFun): LambdaTreeNodeConfig<T, R> // 设置名称字段Lambda函数(链式)
      ├── getChildrenKeyFun(): SerFunction<T, List<T>> // 获取子节点字段Lambda函数
      ├── setChildrenKeyFun(childrenKeyFun): LambdaTreeNodeConfig<T, R> // 设置子节点字段Lambda函数(链式)
      ├── getIdKey(): String                      // 重写:获取ID字段名
      ├── getParentIdKey(): String                // 重写:获取父节点ID字段名
      ├── getWeightKey(): String                  // 重写:获取权重字段名
      ├── getNameKey(): String                    // 重写:获取名称字段名
      └── getChildrenKey(): String                // 重写:获取子节点字段名

# 🚀 快速开始

# 基本使用

// 定义实体类
class Menu {
    private Long id;
    private Long parentId;
    private String name;
    private Integer sort;
    private List<Menu> children;

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

// 创建Lambda配置
LambdaTreeNodeConfig<Menu, Long> config = new LambdaTreeNodeConfig<>();

// 使用方法引用配置字段
config.setIdKeyFun(Menu::getId)
    .setParentIdKeyFun(Menu::getParentId)
    .setNameKeyFun(Menu::getName)
    .setWeightKeyFun(Menu::getSort)
    .setChildrenKeyFun(Menu::getChildren);

// 构建树
List<Menu> menuList = getMenuList(); // 从数据库获取菜单列表
List<Menu> menuTree = BeanTree.build(menuList, 0L, config);

# 混合使用Lambda和字符串配置

// 创建Lambda配置
LambdaTreeNodeConfig<Menu, Long> config = new LambdaTreeNodeConfig<>();

// 使用Lambda配置ID和父ID
config.setIdKeyFun(Menu::getId)
    .setParentIdKeyFun(Menu::getParentId);

// 使用传统字符串配置其他属性
config.setNameKey("menuName")
    .setWeightKey("order")
    .setChildrenKey("subMenus");

// 构建树
List<Map<String, Object>> tree = TreeUtil.build(menuList, 0L, config);

# 📖 详细方法

# Lambda函数配置

# getIdKeyFun()

  • 功能:获取ID字段的Lambda函数

  • 返回值:ID字段的Lambda函数

  • 示例:

    SerFunction<Menu, Long> idFun = config.getIdKeyFun();
    

# setIdKeyFun(idKeyFun)

  • 功能:设置ID字段的Lambda函数

  • 参数:idKeyFun - ID字段的Lambda函数,通常使用方法引用

  • 返回值:当前配置实例,支持链式调用

  • 使用场景:使用Lambda表达式配置ID字段

  • 示例:

    config.setIdKeyFun(Menu::getId);
    

# getParentIdKeyFun()

  • 功能:获取父节点ID字段的Lambda函数

  • 返回值:父节点ID字段的Lambda函数

  • 示例:

    SerFunction<Menu, Long> parentIdFun = config.getParentIdKeyFun();
    

# setParentIdKeyFun(parentIdKeyFun)

  • 功能:设置父节点ID字段的Lambda函数

  • 参数:parentIdKeyFun - 父节点ID字段的Lambda函数

  • 返回值:当前配置实例,支持链式调用

  • 使用场景:使用Lambda表达式配置父节点ID字段

  • 示例:

    config.setParentIdKeyFun(Menu::getParentId);
    

# getWeightKeyFun()

  • 功能:获取权重字段的Lambda函数

  • 返回值:权重字段的Lambda函数

  • 示例:

    SerFunction<Menu, Comparable<?>> weightFun = config.getWeightKeyFun();
    

# setWeightKeyFun(weightKeyFun)

  • 功能:设置权重字段的Lambda函数

  • 参数:weightKeyFun - 权重字段的Lambda函数

  • 返回值:当前配置实例,支持链式调用

  • 使用场景:使用Lambda表达式配置权重字段

  • 示例:

    config.setWeightKeyFun(Menu::getSort);
    

# getNameKeyFun()

  • 功能:获取名称字段的Lambda函数

  • 返回值:名称字段的Lambda函数

  • 示例:

    SerFunction<Menu, CharSequence> nameFun = config.getNameKeyFun();
    

# setNameKeyFun(nameKeyFun)

  • 功能:设置名称字段的Lambda函数

  • 参数:nameKeyFun - 名称字段的Lambda函数

  • 返回值:当前配置实例,支持链式调用

  • 使用场景:使用Lambda表达式配置名称字段

  • 示例:

    config.setNameKeyFun(Menu::getName);
    

# getChildrenKeyFun()

  • 功能:获取子节点字段的Lambda函数

  • 返回值:子节点字段的Lambda函数

  • 示例:

    SerFunction<Menu, List<Menu>> childrenFun = config.getChildrenKeyFun();
    

# setChildrenKeyFun(childrenKeyFun)

  • 功能:设置子节点字段的Lambda函数

  • 参数:childrenKeyFun - 子节点字段的Lambda函数

  • 返回值:当前配置实例,支持链式调用

  • 使用场景:使用Lambda表达式配置子节点字段

  • 示例:

    config.setChildrenKeyFun(Menu::getChildren);
    

# 重写的父类方法

# getIdKey()

  • 功能:获取ID字段名

  • 返回值:如果设置了Lambda函数,则返回函数对应的字段名;否则返回父类配置的字段名

  • 示例:

    config.setIdKeyFun(Menu::getId);
    Console.log(config.getIdKey()); // 输出: id
    

# getParentIdKey()

  • 功能:获取父节点ID字段名

  • 返回值:如果设置了Lambda函数,则返回函数对应的字段名;否则返回父类配置的字段名

  • 示例:

    config.setParentIdKeyFun(Menu::getParentId);
    Console.log(config.getParentIdKey()); // 输出: parentId
    

# getWeightKey()

  • 功能:获取权重字段名

  • 返回值:如果设置了Lambda函数,则返回函数对应的字段名;否则返回父类配置的字段名

  • 示例:

    config.setWeightKeyFun(Menu::getSort);
    Console.log(config.getWeightKey()); // 输出: sort
    

# getNameKey()

  • 功能:获取名称字段名

  • 返回值:如果设置了Lambda函数,则返回函数对应的字段名;否则返回父类配置的字段名

  • 示例:

    config.setNameKeyFun(Menu::getName);
    Console.log(config.getNameKey()); // 输出: name
    

# getChildrenKey()

  • 功能:获取子节点字段名

  • 返回值:如果设置了Lambda函数,则返回函数对应的字段名;否则返回父类配置的字段名

  • 示例:

    config.setChildrenKeyFun(Menu::getChildren);
    Console.log(config.getChildrenKey()); // 输出: children
    

# 🎨 使用场景

# 1. 实体类树构建

// 定义部门实体
class Department {
    private Long id;
    private Long parentId;
    private String deptName;
    private Integer orderNum;
    private List<Department> subDepts;

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

// 创建Lambda配置
LambdaTreeNodeConfig<Department, Long> config = new LambdaTreeNodeConfig<>();
config.setIdKeyFun(Department::getId)
    .setParentIdKeyFun(Department::getParentId)
    .setNameKeyFun(Department::getDeptName)
    .setWeightKeyFun(Department::getOrderNum)
    .setChildrenKeyFun(Department::getSubDepts);

// 从数据库获取部门列表
List<Department> deptList = departmentService.findAll();

// 构建部门树
List<Department> deptTree = BeanTree.build(deptList, 0L, config);

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

# 2. 动态字段配置

// 定义动态实体类
class DynamicEntity {
    private String uuid;
    private String parentUuid;
    private String title;
    private Integer priority;
    private List<DynamicEntity> items;

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

// 创建Lambda配置
LambdaTreeNodeConfig<DynamicEntity, String> config = new LambdaTreeNodeConfig<>();

// 根据不同业务场景动态配置
if (isNewVersion) {
    config.setIdKeyFun(DynamicEntity::getUuid)
        .setParentIdKeyFun(DynamicEntity::getParentUuid);
} else {
    config.setIdKey("id")
        .setParentIdKey("parentId");
}

config.setNameKeyFun(DynamicEntity::getTitle)
    .setWeightKeyFun(DynamicEntity::getPriority)
    .setChildrenKeyFun(DynamicEntity::getItems);

// 构建树
List<DynamicEntity> tree = BeanTree.build(entityList, "0", config);

# 3. 结合BeanTree使用

// 定义菜单实体
class Menu {
    private Long id;
    private Long parentId;
    private String name;
    private Integer sort;
    private List<Menu> children;

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

// 创建Lambda配置
LambdaTreeNodeConfig<Menu, Long> config = new LambdaTreeNodeConfig<>();
config.setIdKeyFun(Menu::getId)
    .setParentIdKeyFun(Menu::getParentId)
    .setNameKeyFun(Menu::getName)
    .setWeightKeyFun(Menu::getSort)
    .setChildrenKeyFun(Menu::getChildren);

// 使用BeanTree构建实体树
List<Menu> menuList = menuService.findAll();
List<Menu> menuTree = BeanTree.build(menuList, 0L, config);

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

# 💡 注意事项

  1. 泛型类型:

    • T 是方法对象类型,通常是实体类
    • R 是返回值类型,通常是ID的类型(如Long、String等)
  2. Lambda表达式:

    • 必须使用SerFunction类型,支持序列化
    • 通常使用方法引用(::)来简化代码
  3. 字段名获取:

    • Lambda函数通过LambdaUtil.getFieldName()获取字段名
    • 支持私有字段,会通过反射获取
  4. 兼容父类:

    • 可以混合使用Lambda配置和传统字符串配置
    • Lambda配置优先级高于字符串配置
  5. 序列化支持:

    • 实现了Serializable接口,可以用于网络传输和持久化
    • Lambda函数必须是可序列化的
  6. 性能考虑:

    • Lambda函数的字段名获取是通过反射实现的,首次调用会有一定开销
    • 建议将配置对象缓存起来,避免重复创建

# 🚀 性能优化

  • 对于频繁使用的配置,建议将配置对象缓存为静态常量
  • 优先使用方法引用而非匿名Lambda表达式,提高性能
  • 避免在循环中创建配置对象,减少对象创建开销
  • 对于固定配置,考虑使用单例模式管理

# 🔍 最佳实践

  1. 类型安全:优先使用Lambda配置,利用编译时检查避免字段名错误
  2. 代码可读性:使用方法引用使配置更直观,便于维护
  3. 配置复用:将通用配置封装为静态方法或常量,提高代码复用性
  4. 动态适配:根据不同业务场景灵活选择Lambda或字符串配置
  5. 注释说明:对复杂配置添加注释,说明配置的用途和规则
  6. 异常处理:确保Lambda函数指向的字段存在,避免运行时错误

# 📝 总结

LambdaTreeNodeConfig 是 Hutool 树结构模块中的一个重要扩展,它引入了 Lambda 表达式支持,为树结构配置提供了类型安全的解决方案。通过使用方法引用,开发者可以避免硬编码字段名,提高代码的可维护性和可读性。

无论是构建实体类树还是动态配置字段,LambdaTreeNodeConfig 都能提供灵活、安全的配置方式。它继承了 TreeNodeConfig 的所有功能,并在此基础上添加了 Lambda 支持,实现了向下兼容。

在实际开发中,建议优先使用 LambdaTreeNodeConfig,特别是在实体类字段可能发生变化的场景下,它能有效避免因字段名变更导致的运行时错误,提高代码的健壮性。

树节点配置-TreeNodeConfig
树节点基类-TreeNode

← 树节点配置-TreeNodeConfig 树节点基类-TreeNode→

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