在 Web
前端工程中经常会使用到树形结构数据,即所谓数据嵌套,不同数据的之间通过父节点编号从而实现串联。
这里列个简单的数据样式更直观的说明:
[
{
"id": "3795d651-2243-415d-be4b-3138f6cd5829",
"pid": "",
"name": "Virginia Gaylord",
"childNode": [
{
"id": "0374718d-e21d-4d8a-ac56-c02fd87c8f63",
"pid": "3795d651-2243-415d-be4b-3138f6cd5829",
"name": "Darnell Price",
"childNode": [
{
"id": "042e4180-47c5-4f90-934e-f383ed7a33be",
"pid": "0374718d-e21d-4d8a-ac56-c02fd87c8f63",
"name": "Marianne Bednar",
"childNode": []
}
]
}
]
},
{
"id": "4467edda-08af-402d-b66a-4b055b5c0111",
"pid": "",
"name": "Carolyn Murray",
"childNode": [
{
"id": "458c5227-391b-43e7-826b-4fcc332b44e3",
"pid": "4467edda-08af-402d-b66a-4b055b5c0111",
"name": "Irma Mante",
"childNode": []
}
]
}
]
针对此类数据的构建重心我们应该放在后端中,前端更多的业务是进行数据的交互,尽可能的减少数据的处理工作。
下面就详细介绍如果通过 Java 列表构建上述数据结构。
1. 创建DTO
首先先创建一个 DTO
类,这里限于篇幅则省去 get、set
方法,请自行添加。
public class TreeNode {
private String id;
/**
* 父节点 ID
*/
private String pid;
private String name;
private List<TreeNode> childNode;
}
2. 构建思路
下面详细说明一下实现的逻辑。
首先遍历未构建的数据集合,若节点的父节点 ID
为空,则说明该该节点为首级节点,直接将该节点添加至结果集即可。若节点的父节点 ID
不为空,则表明表明接待你存在父节点,因此根据父节点 ID
获取父节点,从而将当前节点添加到父节点的子集合之中即可。
3. 代码实现
确定了实现逻辑就可以尝试代码实现了,上述步骤的代码实现如下。
需要注意在获取父节点的子集合之后不能直接添加当前节点,而需要额外一步判空处理防止空指针异常。
/**
* 树形数据构建
*
* @param list 原始数据列表
*/
public List<TreeNode> buildTree(List<TreeNode> list) {
// 通过 Map 遍历集合, 便于后于通过节点 ID 获取节点
Map<String, TreeNode> nodeMap = new HashMap<>();
for (TreeNode node : list) {
nodeMap.put(node.getId(), node);
}
List<TreeNode> trees = new ArrayList<>();
for (TreeNode node : list) {
// 获取节点父节点
TreeNode parent = nodeMap.get(node.getPid());
if (parent != null) {
// 存在父节点, 获取父节点子节点列表
List<TreeNode> children = parent.getChildNode();
if (children == null) {
// 防止父节点子节点列表为空
children = new ArrayList<>();
}
// 将当前节点添加到父节点中
children.add(node);
parent.setChildNode(children);
} else {
// 不存在父节点,该节点为首节点
trees.add(node);
}
}
return trees;
}