Java构建树结构的公共方法

一、前提

  • pId需要传入用来确认第一级的父节点,而且pId可以为null。
  • 树实体类必须实现:TreeNode接口
  • MyTreeVo必须有这三个属性:id、pId、children
  • 可以根据不同需求,配置TreeNode和MyTreeVo中固定的属性

二、代码

  • 定义TreeNode接口
public interface TreeNode {
    String getId();
    String getpId();
    List getChildren();
}

  • 需要将pId作为参数传入,在方法中添加一个pId参数,用于确认第一级的父节点。
    -- 这个示例代码中,buildTree方法接收两个参数,一个是泛型类型的参数List,另一个是pId,用于确认第一级的父节点。在找到所有的根节点后,我们需要对每个根节点调用buildChildren方法,递归构建子节点。
    -- 以便支持传入的pId作为顶级节点
public class TreeBuilder {
    /**
     * @param nodes 需要构建的nodes,不要继承 TreeNode,且需要有 TreeNode 下的三个方法
     * @param pId 父id。为null则是所有pid为null的是顶级节点;不为null,则是从给的pId往下查询并构建树
     **/
    public static <T extends TreeNode> List<T> buildTree(List<T> nodes, String pId) {
        List<T> roots = new ArrayList<>();
        for (T node : nodes) {
            if (node.getId().equals(pId) || (node.getParentId() == null && (pId == null || pId.equals(node.getId())))) {
                roots.add(node);
            }
        }
        for (T root : roots) {
            buildChildren(root, nodes);
        }
        return roots;
    }

    private static <T extends TreeNode> void buildChildren(T node, List<T> nodes) {
        for (T child : nodes) {
            if (child.getParentId() != null && child.getParentId().equals(node.getId())) {
                node.getChildren().add(child);
                buildChildren(child, nodes);
            }
        }
    }
}

  • 构建到几级
    -- 如果再增加一个参数,构建到树的第几层该如何实现?
    -- 根据需求,如果增加一个参数来控制构建到树的第几层,可以在buildChildren方法中添加一个level参数,用于记录当前节点的层数。在递归构建子节点时,如果当前节点的层数小于指定的层数,则继续递归构建子节点,否则停止递归。以下是修改后的Java示例代码:
public class TreeBuilder {
     
     /**
      * @param level 级别 从1开始。1是最顶层
      **/
    public static <T extends TreeNode> List<T> buildTree(List<T> nodes, String pId, int level) {
        List<T> roots = new ArrayList<>();
        for (T node : nodes) {
            if (node.getId().equals(pId) || (node.getParentId() == null && (pId == null || pId.equals(node.getId())))) {
                roots.add(node);
            }
        }
        for (T root : roots) {
            buildChildren(root, nodes, level, 1);
        }
        return roots;
    }

    private static <T extends TreeNode> void buildChildren(T node, List<T> nodes, int level, int currentLevel) {
        if (currentLevel >= level) {
            return;
        }
        for (T child : nodes) {
            if (child.getParentId() != null && child.getParentId().equals(node.getId())) {
                if (node.getChildren() == null) {
                    node.setChildren(new ArrayList<>());
                }
                node.getChildren().add(child);
                buildChildren(child, nodes, level, currentLevel + 1);
            }
        }
    }
}


三、使用

1、实现TreeNode接口

public class MyTreeVo implements TreeNode {

    /**
     * 主键
     */
    private String id;

    /**
     * 父节点ID
     */
    private String pId;

    /**
     * 子级
     */
    private List<MyTreeVo> children = Lists.newArrayList();

    //其他属性……

    public List<MyTreeVo> getChildren() {
        return children;
    }

    public String getId() {
        return id;
    }

    public String getpId() {
        return pId;
    }

    //其他属性的getter、setter……

2、使用

-- pId可以传入null,也可以传入需要从哪个节点(X)开始构造的 X的id
-- pId比如可以传入3、样例中的 “二、噢噢噢噢”的id=“e6ee51485389495cb923a122be800012”。然后构建出来的,就是“二、噢噢噢噢”的下级树

List<MyTreeVo> tree = TreeUtilQz.buildTree(vos,null);
//tree就是构建好的树结构数据

3、样例

{
    "data": [
        {
            "id": "e6ee51485389495cb923a122be800011",
            "pId": "",
            "name": "一、钢管钢管",
            "children": [
                {
                    "id": "e6ee51485389495cb923a122be800014",
                    "pId": "e6ee51485389495cb923a122be800011",
                    "name": "(二)嘎嘎嘎嘎嘎",
                    "children": []
                },
                {
                    "id": "e6ee51485389495cb923a122be800013",
                    "pId": "e6ee51485389495cb923a122be800011",
                    "name": "(一)顶顶顶顶",
                    "children": []
                }
            ]
        },
        {
            "id": "e6ee51485389495cb923a122be800012",
            "pId": "",
            "name": "二、噢噢噢噢",
            "children": [
                {
                    "id": "e6ee51485389495cb923a122be800015",
                    "pId": "e6ee51485389495cb923a122be800012",
                    "name": "二的下级",
                    "children": [
                        {
                            "id": "e6ee51485389495cb923a122be800016",
                            "pId": "e6ee51485389495cb923a122be800015",
                            "name": "二的下级的下级",
                            "children": []
                        }
                    ]
                }
            ]
        }
    ]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
构建树形结构,你可以使用Java中的树形数据结构,如树或二叉树。你可以将数据存储在节点中,然后使用递归方法构建树形结构。 下面是一个简单的示例代码,用于构建一个二叉树并统计汇总: ```java class Node { int value; Node left; Node right; Node(int value) { this.value = value; left = null; right = null; } } class BinaryTree { Node root; BinaryTree() { root = null; } // 添加节点 void insert(int value) { root = insert(root, value); } Node insert(Node node, int value) { if (node == null) { node = new Node(value); return node; } if (value < node.value) { node.left = insert(node.left, value); } else if (value > node.value) { node.right = insert(node.right, value); } return node; } // 统计汇总 int sum(Node node) { if (node == null) { return 0; } return node.value + sum(node.left) + sum(node.right); } } public class TreeDemo { public static void main(String[] args) { BinaryTree tree = new BinaryTree(); // 添加节点 tree.insert(5); tree.insert(3); tree.insert(7); tree.insert(1); tree.insert(9); // 统计汇总 int total = tree.sum(tree.root); System.out.println("Total: " + total); } } ``` 在这个示例中,我们首先定义了一个`Node`类来表示树的节点,然后定义了一个`BinaryTree`类来表示二叉树,并提供了一个`insert`方法来添加节点。最后我们提供了一个`sum`方法来统计汇总,使用递归方法遍历整个树来计算节点值的总和。 在`main`方法中,我们创建了一个二叉树并添加了一些节点,最后调用`sum`方法来计算节点值的总和。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值