列表集合构造树形数据


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;
}

文章作者: 烽火戏诸诸诸侯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 烽火戏诸诸诸侯 !
  目录