目录
核心思路
1. 定义树节点数据结构 :
2. 获取扁平化数据 :
3. 构建树形结构 :
4. 暴露接口 :
TreeService.java:树形构建服务
解释 :
总结
下拉框(Dropdown)展示层级结构数据(如部门、分类等)是一种常见的需求。为了提供用户友好的交互体验,通常需要将扁平化的数据转换为树状结构,并通过接口暴露给前端。
核心思路
实现这一功能的关键在于 将扁平化的数据列表转换为具有父子关系的树形结构 。这通常涉及以下几个步骤:
1. 定义树节点数据结构 :
首先,需要一个数据模型来表示树中的每一个节点。这个节点应该包含至少以下信息:
- id :节点的唯一标识符。
- parentId :父节点的标识符,用于建立层级关系。根节点的 parentId 通常为 null 或特定值(如 0 )。
- label 或 name :节点显示文本。
- children :一个列表,用于存储当前节点的子节点。
2. 获取扁平化数据 :
从数据库或其他数据源中获取所有需要展示的数据。这些数据通常是扁平化的列表,每个记录包含 id 和 parentId 。
3. 构建树形结构 :
这是核心逻辑所在。通过遍历扁平化数据,利用 id 和 parentId 之间的关系,将节点组织成树形结构。常用的方法是使用一个 Map 来存储所有节点,以便通过 id 快速查找,然后遍历节点,将其添加到其父节点的 children 列表中。
4. 暴露接口 :
通过 RESTful API 将构建好的树形结构数据暴露给前端。前端可以调用此接口获取数据,并使用相应的 UI 组件(如 Ant Design 的 TreeSelect 或 Element UI 的 ElTree )进行渲染。
TreeService.java:树形构建服务
在 Java 后端, TreeService 类是实现树形结构构建的核心组件。它的主要职责是封装将扁平数据转换为树形数据的逻辑。
以下是TreeService.java 的核心代码片段和解释:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
// ... existing code ...
public class TreeService {
// ... existing code ...
/**
* 将扁平化的节点列表构建成树形结构。
* @param nodes 扁平化的节点列表,每个节点包含id、parentId等信息。
* @return 树形结构的根节点列表。
*/
public List<TreeNode> buildTree(List<TreeNode> nodes) {
List<TreeNode> rootNodes = new ArrayList<>();
Map<String, TreeNode> nodeMap = new HashMap<>();
// 第一次遍历:将所有节点放入Map中,方便通过ID查找
for (TreeNode node : nodes) {
nodeMap.put(node.getId(), node);
}
// 第二次遍历:构建父子关系
for (TreeNode node : nodes) {
String parentId = node.getParentId();
// 如果有父节点且父节点存在于Map中,则将当前节点添加到父节点的children列表中
if (parentId != null && nodeMap.containsKey(parentId)) {
TreeNode parentNode = nodeMap.get(parentId);
if (parentNode.getChildren() == null) {
parentNode.setChildren(new ArrayList<>());
}
parentNode.getChildren().add(node);
} else {
// 没有父节点或者父节点不存在(即为根节点),则添加到根节点列表中
rootNodes.add(node);
}
}
return rootNodes;
}
}
解释 :
1. buildTree(List<TreeNode> nodes) 方法 :这是 TreeService 的核心方法,接收一个扁平化的 TreeNode 列表作为输入。
2. nodeMap :使用 HashMap 来存储所有节点,键为节点的 id ,值为 TreeNode 对象。这样可以在 O(1) 的时间复杂度内通过 id 查找任何节点,极大地提高了构建效率。
3. 两次遍历 :
- 第一次遍历 :将所有节点放入 nodeMap 中。这一步是为了确保在构建父子关系时,所有节点都已可被快速访问。
- 第二次遍历 :遍历原始的扁平化节点列表。对于每个节点,检查其 parentId 。如果 parentId 不为空且对应的父节点存在于 nodeMap 中,则将当前节点添加到父节点的 children 列表中。如果 parentId 为空或父节点不存在(这通常意味着它是顶层节点),则将其添加到 rootNodes 列表中。
4. 返回 rootNodes :最终返回的 rootNodes 列表包含了所有顶层节点,每个顶层节点都递归地包含了其所有子节点,从而形成了完整的树形结构。
总结
通过 TreeService 中的 buildTree 方法,我们可以高效地将从数据库查询到的扁平化数据转换为前端所需的树形结构。这种模式清晰地分离了数据获取、数据转换和接口暴露的职责,使得代码更具可维护性和扩展性。前端只需调用相应的接口,即可获取并渲染出美观且功能完善的树状下拉框。