Department类通过id、name、parentId字段和List<Department> children实现树结构,支持O(n)建树、递归查询/遍历/路径生成,并需事务化处理增删改以保证内存与数据库一致。

用 Java 类建模部门树结构
部门树本质是父子关系的递归数据结构,核心是定义一个 Department 类,自身持有对子部门的引用。不需要额外引入“面向对象的数据结构”这类模糊概念——Java 的类、集合和泛型就是天然的面向对象载体。
关键设计点:
- 每个部门包含基础字段:id、name、parentId(用于构建关系)
- 用 List<Department> 存储 children,支持动态增删与遍历
- 不依赖父引用(parent 字段)也能工作;若需向上追溯(如查所属事业部),可按需添加 parent 字段并手动维护,或通过 Map 缓存 parentId → parent 映射
从扁平列表构造无限层级树
数据库通常返回扁平的部门列表(每条记录含 id 和 parentId)。构建树只需一次遍历 + 哈希映射,时间复杂度 O(n):
- 先将所有部门按 id 存入 Map<Long, Department>
- 再次遍历列表:若 parentId ≠ null 且存在对应父节点,则将当前部门 add 到父节点的 children 列表中
- 最后筛选出 parentId 为 null(或 0/-1)的节点,即根节点集合
这样得到的是一组根节点,每个都自带完整子树,天然支持任意深度嵌套。
立即学习“Java免费学习笔记(深入)”;
封装递归操作方法
把常用递归逻辑封装成 Department 类的实例方法或工具方法,避免散落各处:
- 查找指定 ID 的部门(含任意子级):递归 searchById(id) —— 先查自身,再逐个递归 children
- 获取所有叶子部门:递归 collectLeaves() —— children 为空则加入结果,否则继续递归
- 生成路径字符串(如 “总部 > 研发中心 > 后端组”):递归 buildPath(),传入 StringBuilder 或前缀参数
- 注意:Java 默认栈深度约 10000 层,真实业务中极少超 10 层,无需担心栈溢出;若极端场景需要,可用显式栈(Stack/Deque)改写为迭代版
支持修改与持久化的一致性处理
树结构变动(新增、移动、删除)需兼顾内存模型与数据库同步:
- 新增部门:设置好 parentId,插入后调用 buildTree() 重建整棵树,或只局部更新父节点的 children 列表
- 移动部门:先从原父节点 children 中 remove,再 add 到新父节点;同时更新数据库中该部门的 parentId
- 删除部门:递归删除其所有后代(先清 children,再删自己),并同步执行 SQL DELETE WHERE id IN (…)
- 建议用事务包裹数据库操作,并在 Service 层统一管理树结构变更逻辑,避免 DAO 层直接暴露 children 集合


















