Java List转树形状结构,过滤某些节点

一段AI生成的代码,供参考+思考

有一个java对象列表,里面有code和pcode两个字段,pcode代表上级code,需要将这个列表转换成树形结构,并且去除没有选中的分支


我的需求

有一个java对象列表,里面有code和pcode两个字段,pcode代表上级code,需要将这个列表转换成树形结构

AI回答

public class TreeNode {
    private String code;
    private String pcode;
    private List<TreeNode> children;

    public TreeNode(String code, String pcode) {
        this.code = code;
        this.pcode = pcode;
        this.children = new ArrayList<>();
    }

    // getters and setters
    public String getCode() { return code; }
    public void setCode(String code) { this.code = code; }
    public String getPcode() { return pcode; }
    public void setPcode(String pcode) { this.pcode = pcode; }
    public List<TreeNode> getChildren() { return children; }
    public void setChildren(List<TreeNode> children) { this.children = children; }
    public void addChild(TreeNode child) { children.add(child); }
}

接下来,你需要一个方法来构建树。这个方法会遍历整个列表,并根据 pcode 将每个节点添加到它的父节点下面。以下是实现该功能的方法:

public class TreeBuilder {

    public static TreeNode buildTree(List<TreeNode> nodes) {
        Map<String, TreeNode> nodeMap = new HashMap<>();
        TreeNode root = null;

        for (TreeNode node : nodes) {
            nodeMap.put(node.getCode(), node);
            if (node.getPcode().equals("root")) { // 假设根节点的 pcode 为 "root"
                root = node;
            } else {
                TreeNode parentNode = nodeMap.get(node.getPcode());
                if (parentNode != null) {
                    parentNode.addChild(node);
                } else {
                    System.out.println("Warning: Parent not found for node with code " + node.getCode());
                }
            }
        }

        return root;
    }
}

在这个例子中,我们首先创建了一个 HashMap 来存储所有的节点,键是节点的 code,值是节点本身。然后,对于列表中的每一个节点,我们检查它的 pcode 并在 nodeMap 中查找其父节点。如果找到父节点,则将当前节点添加到父节点的 children 列表中。如果找不到父节点(这通常意味着父节点还没有被处理),则打印警告信息。

请注意,这个例子假设根节点的 pcode 是 "root"。你需要根据实际情况调整这个条件。

如果你需要一个完整的示例代码,请告诉我,我可以为你提供一个从列表构建树的完整示例。


继续追问

如果这个列表中还有一个字段check,标记是否被选中,这个树中叶子结点没有被选中的话,此分支需要去掉

AI回答

在这种情况下,我们需要对构建好的树进行修剪,移除所有未被选中的叶子节点及其未被选中的父节点分支。为了实现这一点,我们可以添加一个新的方法来遍历树并移除未选中的叶子节点以及它们的未选中父节点。这里假设 TreeNode 类已经扩展以包含一个布尔类型的 check 字段,表示该节点是否被选中。

首先,让我们更新 TreeNode 类的定义:

public class TreeNode {
    private String code;
    private String pcode;
    private boolean check;
    private List<TreeNode> children;

    public TreeNode(String code, String pcode, boolean check) {
        this.code = code;
        this.pcode = pcode;
        this.check = check;
        this.children = new ArrayList<>();
    }

    // Getters and setters
    public String getCode() { return code; }
    public void setCode(String code) { this.code = code; }
    public String getPcode() { return pcode; }
    public void setPcode(String pcode) { this.pcode = pcode; }
    public boolean isCheck() { return check; }
    public void setCheck(boolean check) { this.check = check; }
    public List<TreeNode> getChildren() { return children; }
    public void setChildren(List<TreeNode> children) { this.children = children; }
    public void addChild(TreeNode child) { children.add(child); }
}

接下来,我们需要添加一个方法来修剪树。这个方法应该递归地检查每个节点及其子节点,并移除所有未选中的叶子节点以及它们未选中的父节点。这里是一个实现该功能的方法:

public class TreeBuilder {

    public static TreeNode buildTree(List<TreeNode> nodes) {
        Map<String, TreeNode> nodeMap = new HashMap<>();
        TreeNode root = null;

        for (TreeNode node : nodes) {
            nodeMap.put(node.getCode(), node);
            if (node.getPcode().equals("root")) {
                root = node;
            } else {
                TreeNode parentNode = nodeMap.get(node.getPcode());
                if (parentNode != null) {
                    parentNode.addChild(node);
                } else {
                    System.out.println("Warning: Parent not found for node with code " + node.getCode());
                }
            }
        }

        pruneUnselectedNodes(root);

        return root;
    }

    private static void pruneUnselectedNodes(TreeNode node) {
        if (node == null) {
            return;
        }

        // Prune the subtree
        Iterator<TreeNode> iterator = node.getChildren().iterator();
        while (iterator.hasNext()) {
            TreeNode child = iterator.next();
            pruneUnselectedNodes(child);

            // If the child is unselected and has no selected children, remove it.
            if (!child.isCheck() && child.getChildren().isEmpty()) {
                iterator.remove();
            }
        }

        // If the node has no selected children and is unselected, mark it as removable.
        if (!node.isCheck() && node.getChildren().isEmpty()) {
            node.setCheck(false);
        }
    }
}

在这个实现中,我们添加了一个名为 pruneUnselectedNodes 的私有方法,它递归地遍历树,并在适当的情况下移除未选中的叶子节点。如果一个节点没有被选中,并且它也没有任何被选中的子节点,那么该节点会被标记为未选中或直接从树中移除。

请注意,如果一个节点没有被选中并且它的所有子节点也都没有被选中,那么这个节点也会被标记为未选中。这意味着如果根节点没有被选中并且它所有的子节点都没有被选中,那么整棵树将被标记为未选中。

如果你需要一个完整的示例代码,包括如何初始化数据列表,请告诉我,我可以为你提供一个完整的示例。


这里可以看到AI提示我可以产生完整的例子,这当然是个大福利,直接CV就能搞定需求,接下来是AI生成的完整代码


AI回答

当然可以。以下是一个完整的示例代码,包括如何初始化数据列表、构建树以及修剪未选中的节点:

import java.util.*;

public class TreeBuilderExample {

    public static void main(String[] args) {
        List<TreeNode> nodes = new ArrayList<>();
        nodes.add(new TreeNode("1", "root", true));
        nodes.add(new TreeNode("2", "1", true));
        nodes.add(new TreeNode("3", "1", false));
        nodes.add(new TreeNode("4", "2", false));
        nodes.add(new TreeNode("5", "2", true));
        nodes.add(new TreeNode("6", "5", false));
        nodes.add(new TreeNode("7", "5", true));
        nodes.add(new TreeNode("8", "7", false));

        TreeNode root = TreeBuilder.buildTree(nodes);
        
        // 打印结果
        printTree(root, "");
    }

    private static void printTree(TreeNode node, String indent) {
        if (node == null) {
            return;
        }

        System.out.println(indent + node.getCode() + " (Selected: " + node.isCheck() + ")");
        for (TreeNode child : node.getChildren()) {
            printTree(child, indent + "  ");
        }
    }
}

class TreeNode {
    private String code;
    private String pcode;
    private boolean check;
    private List<TreeNode> children;

    public TreeNode(String code, String pcode, boolean check) {
        this.code = code;
        this.pcode = pcode;
        this.check = check;
        this.children = new ArrayList<>();
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getPcode() {
        return pcode;
    }

    public void setPcode(String pcode) {
        this.pcode = pcode;
    }

    public boolean isCheck() {
        return check;
    }

    public void setCheck(boolean check) {
        this.check = check;
    }

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

    public void setChildren(List<TreeNode> children) {
        this.children = children;
    }

    public void addChild(TreeNode child) {
        children.add(child);
    }
}

class TreeBuilder {

    public static TreeNode buildTree(List<TreeNode> nodes) {
        Map<String, TreeNode> nodeMap = new HashMap<>();
        TreeNode root = null;

        for (TreeNode node : nodes) {
            nodeMap.put(node.getCode(), node);
            if (node.getPcode().equals("root")) {
                root = node;
            } else {
                TreeNode parentNode = nodeMap.get(node.getPcode());
                if (parentNode != null) {
                    parentNode.addChild(node);
                } else {
                    System.out.println("Warning: Parent not found for node with code " + node.getCode());
                }
            }
        }

        pruneUnselectedNodes(root);

        return root;
    }

    private static void pruneUnselectedNodes(TreeNode node) {
        if (node == null) {
            return;
        }

        // Prune the subtree
        Iterator<TreeNode> iterator = node.getChildren().iterator();
        while (iterator.hasNext()) {
            TreeNode child = iterator.next();
            pruneUnselectedNodes(child);

            // If the child is unselected and has no selected children, remove it.
            if (!child.isCheck() && child.getChildren().isEmpty()) {
                iterator.remove();
            }
        }

        // If the node has no selected children and is unselected, mark it as removable.
        if (!node.isCheck() && node.getChildren().isEmpty()) {
            node.setCheck(false);
        }
    }
}

还贴心的来了一个提示,必须给赞。

1.初始化:

我们创建了一个 nodes 列表,并向其中添加了一些 TreeNode 实例。
每个节点都有一个 code(标识符)、一个 pcode(父节点的标识符)以及一个 check 标志(表示是否被选中)。

2.构建树:

使用 buildTree 方法构建树结构。这个方法创建了一个 nodeMap 用于存储所有节点,并通过 pcode 将子节点与父节点关联起来。
在构建完成后,调用 pruneUnselectedNodes 方法来移除未选中的节点。

3.修剪未选中的节点:

pruneUnselectedNodes 方法递归地遍历树,并移除那些未选中的叶子节点。
如果一个节点未被选中并且没有选中的子节点,它会被从树中移除。

4.打印结果:

最后,我们定义了一个 printTree 方法来打印出树的结构。这可以帮助我们验证树是否正确构建。

你可以运行这段代码来看看最终构建出来的树是什么样的。如果需要进一步的帮助或修改,请随时告知。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容