Java List轉(zhuǎn)樹形狀結(jié)構(gòu),過濾某些節(jié)點(diǎn)

一段AI生成的代碼扔亥,供參考+思考

有一個(gè)java對(duì)象列表场躯,里面有code和pcode兩個(gè)字段谈为,pcode代表上級(jí)code旅挤,需要將這個(gè)列表轉(zhuǎn)換成樹形結(jié)構(gòu),并且去除沒有選中的分支


我的需求

有一個(gè)java對(duì)象列表伞鲫,里面有code和pcode兩個(gè)字段粘茄,pcode代表上級(jí)code,需要將這個(gè)列表轉(zhuǎn)換成樹形結(jié)構(gòu)

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

接下來秕脓,你需要一個(gè)方法來構(gòu)建樹柒瓣。這個(gè)方法會(huì)遍歷整個(gè)列表,并根據(jù) pcode 將每個(gè)節(jié)點(diǎn)添加到它的父節(jié)點(diǎn)下面吠架。以下是實(shí)現(xiàn)該功能的方法:

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")) { // 假設(shè)根節(jié)點(diǎn)的 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;
    }
}

在這個(gè)例子中芙贫,我們首先創(chuàng)建了一個(gè) HashMap 來存儲(chǔ)所有的節(jié)點(diǎn),鍵是節(jié)點(diǎn)的 code傍药,值是節(jié)點(diǎn)本身磺平。然后,對(duì)于列表中的每一個(gè)節(jié)點(diǎn)拐辽,我們檢查它的 pcode 并在 nodeMap 中查找其父節(jié)點(diǎn)拣挪。如果找到父節(jié)點(diǎn),則將當(dāng)前節(jié)點(diǎn)添加到父節(jié)點(diǎn)的 children 列表中俱诸。如果找不到父節(jié)點(diǎn)(這通常意味著父節(jié)點(diǎn)還沒有被處理)菠劝,則打印警告信息。

請(qǐng)注意睁搭,這個(gè)例子假設(shè)根節(jié)點(diǎn)的 pcode 是 "root"赶诊。你需要根據(jù)實(shí)際情況調(diào)整這個(gè)條件笼平。

如果你需要一個(gè)完整的示例代碼,請(qǐng)告訴我舔痪,我可以為你提供一個(gè)從列表構(gòu)建樹的完整示例出吹。


繼續(xù)追問

如果這個(gè)列表中還有一個(gè)字段check,標(biāo)記是否被選中辙喂,這個(gè)樹中葉子結(jié)點(diǎn)沒有被選中的話捶牢,此分支需要去掉

AI回答

在這種情況下,我們需要對(duì)構(gòu)建好的樹進(jìn)行修剪巍耗,移除所有未被選中的葉子節(jié)點(diǎn)及其未被選中的父節(jié)點(diǎn)分支秋麸。為了實(shí)現(xiàn)這一點(diǎn),我們可以添加一個(gè)新的方法來遍歷樹并移除未選中的葉子節(jié)點(diǎn)以及它們的未選中父節(jié)點(diǎn)炬太。這里假設(shè) TreeNode 類已經(jīng)擴(kuò)展以包含一個(gè)布爾類型的 check 字段灸蟆,表示該節(jié)點(diǎn)是否被選中。

首先亲族,讓我們更新 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); }
}

接下來炒考,我們需要添加一個(gè)方法來修剪樹。這個(gè)方法應(yīng)該遞歸地檢查每個(gè)節(jié)點(diǎn)及其子節(jié)點(diǎn)霎迫,并移除所有未選中的葉子節(jié)點(diǎn)以及它們未選中的父節(jié)點(diǎn)斋枢。這里是一個(gè)實(shí)現(xiàn)該功能的方法:

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

在這個(gè)實(shí)現(xiàn)中,我們添加了一個(gè)名為 pruneUnselectedNodes 的私有方法知给,它遞歸地遍歷樹瓤帚,并在適當(dāng)?shù)那闆r下移除未選中的葉子節(jié)點(diǎn)。如果一個(gè)節(jié)點(diǎn)沒有被選中涩赢,并且它也沒有任何被選中的子節(jié)點(diǎn)戈次,那么該節(jié)點(diǎn)會(huì)被標(biāo)記為未選中或直接從樹中移除。

請(qǐng)注意筒扒,如果一個(gè)節(jié)點(diǎn)沒有被選中并且它的所有子節(jié)點(diǎn)也都沒有被選中怯邪,那么這個(gè)節(jié)點(diǎn)也會(huì)被標(biāo)記為未選中。這意味著如果根節(jié)點(diǎn)沒有被選中并且它所有的子節(jié)點(diǎn)都沒有被選中花墩,那么整棵樹將被標(biāo)記為未選中悬秉。

如果你需要一個(gè)完整的示例代碼,包括如何初始化數(shù)據(jù)列表观游,請(qǐng)告訴我搂捧,我可以為你提供一個(gè)完整的示例。


這里可以看到AI提示我可以產(chǎn)生完整的例子懂缕,這當(dāng)然是個(gè)大福利允跑,直接CV就能搞定需求,接下來是AI生成的完整代碼


AI回答

當(dāng)然可以。以下是一個(gè)完整的示例代碼聋丝,包括如何初始化數(shù)據(jù)列表索烹、構(gòu)建樹以及修剪未選中的節(jié)點(diǎn):

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);
        
        // 打印結(jié)果
        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);
        }
    }
}

還貼心的來了一個(gè)提示,必須給贊弱睦。

1.初始化:

我們創(chuàng)建了一個(gè) nodes 列表百姓,并向其中添加了一些 TreeNode 實(shí)例。
每個(gè)節(jié)點(diǎn)都有一個(gè) code(標(biāo)識(shí)符)况木、一個(gè) pcode(父節(jié)點(diǎn)的標(biāo)識(shí)符)以及一個(gè) check 標(biāo)志(表示是否被選中)垒拢。

2.構(gòu)建樹:

使用 buildTree 方法構(gòu)建樹結(jié)構(gòu)。這個(gè)方法創(chuàng)建了一個(gè) nodeMap 用于存儲(chǔ)所有節(jié)點(diǎn)火惊,并通過 pcode 將子節(jié)點(diǎn)與父節(jié)點(diǎn)關(guān)聯(lián)起來求类。
在構(gòu)建完成后,調(diào)用 pruneUnselectedNodes 方法來移除未選中的節(jié)點(diǎn)屹耐。

3.修剪未選中的節(jié)點(diǎn):

pruneUnselectedNodes 方法遞歸地遍歷樹尸疆,并移除那些未選中的葉子節(jié)點(diǎn)。
如果一個(gè)節(jié)點(diǎn)未被選中并且沒有選中的子節(jié)點(diǎn)惶岭,它會(huì)被從樹中移除寿弱。

4.打印結(jié)果:

最后,我們定義了一個(gè) printTree 方法來打印出樹的結(jié)構(gòu)按灶。這可以幫助我們驗(yàn)證樹是否正確構(gòu)建症革。

你可以運(yùn)行這段代碼來看看最終構(gòu)建出來的樹是什么樣的。如果需要進(jìn)一步的幫助或修改兆衅,請(qǐng)隨時(shí)告知地沮。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市羡亩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌危融,老刑警劉巖畏铆,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異吉殃,居然都是意外死亡辞居,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門蛋勺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓦灶,“玉大人,你說我怎么就攤上這事抱完≡籼眨” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碉怔。 經(jīng)常有香客問我烘贴,道長(zhǎng),這世上最難降的妖魔是什么撮胧? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任桨踪,我火速辦了婚禮,結(jié)果婚禮上芹啥,老公的妹妹穿的比我還像新娘锻离。我一直安慰自己,他們只是感情好墓怀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布纳账。 她就那樣靜靜地躺著,像睡著了一般捺疼。 火紅的嫁衣襯著肌膚如雪疏虫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天啤呼,我揣著相機(jī)與錄音卧秘,去河邊找鬼。 笑死官扣,一個(gè)胖子當(dāng)著我的面吹牛翅敌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惕蹄,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼蚯涮,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贯吓,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤芜飘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后棒旗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撩荣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年铣揉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片餐曹。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逛拱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出台猴,到底是詐尸還是另有隱情朽合,我是刑警寧澤俱两,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站旁舰,受9級(jí)特大地震影響锋华,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箭窜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一毯焕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磺樱,春花似錦纳猫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至块差,卻和暖如春侵续,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背憨闰。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工状蜗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹉动。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓轧坎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親泽示。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缸血,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容