Java 将树转为List

1、需求,将一棵无关联属性的树(没有id和pid)转化为list存储(通过id和pid关联)

2、思路,该处只能通过广度遍历树获取list。如果使用深度遍历的话,pid将获取不到正确的值。

3、树的结构如下。(无id和pid)

Tree {

    private String     name;

    private String     desc;

    private List<Tree> children;

}
package com.example.demo;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;

/**
 * TreeService.java
 *
 * @author jc
 * @version 2023年06月15日 14:32 
 */
public class TreeService {

    /**
     *   ID索引,为List生成ID使用
     **/
    public static Integer index = 1;

    public static void main(String[] args) {

        //初始化树
        Tree tree = init();

        String json = JSONObject.toJSONString(tree);
        System.out.println(json);
        //将Tree转为List
        List<Tree2List> list = breadthFirstTree2List(tree);
        //将List转为Tree
        Tree root = list2Tree(list);

        String json2 = JSONObject.toJSONString(root);
        System.out.println(json2);

    }

    /**
     * description 广度遍历,将一棵没有ID的树展开为有ID和PID关联的List
     * @param root 
     * @return java.util.List<com.example.demo.Tree2List>
     * @authorjc
     * @date 2023/6/20 13:23
     **/
    public static List<Tree2List> breadthFirstTree2List(Tree root) {

        List<Tree2List> list = new ArrayList<>();
        Queue<Tree> queue = new LinkedList<>();
        if (root == null) {
            return null;
        }
        root.setPid("0");
        //使用UUID也可以 root.setId(UUID.randomUUID().toString());
        root.setId(getIndex().toString());
        queue.offer(root);

        while (!queue.isEmpty()) {
            Tree tree = queue.poll();
            String pid = tree.getId();
            List<Tree> children = tree.getChildren();
            if (children != null) {
                for (Tree child : children) {
                    child.setPid(pid);
                    //使用UUID也可以 child.setId(UUID.randomUUID().toString());
                    child.setId(getIndex().toString());
                    queue.offer(child);
                }
            }
            Tree2List tree2List = new Tree2List();
            tree2List.setId(tree.getId());
            tree2List.setPid(tree.getPid());
            tree2List.setName(tree.getName());
            tree2List.setDesc(tree.getDesc());
            list.add(tree2List);
        }

        return list;

    }

    /**
     * description 将List转化为Tree 
     * @param tree2Lists 
     * @return com.example.demo.Tree
     * @author jc
     * @date 2023/6/20 13:26
     **/
    public static Tree list2Tree(List<Tree2List> tree2Lists) {

        Map<String, List<Tree2List>> listMap = tree2Lists.stream().collect(Collectors.groupingBy(Tree2List::getPid));
        //获取List的根节点
        Tree2List listRoot = listMap.get("0").get(0);
        //组装Tree的根节点
        Tree root = new Tree(listRoot.getPid(), listRoot.getId(), listRoot.getName(), listRoot.getDesc());
        list2TreeRecursion(listMap, root);

        return root;

    }

    /**
     * description 递归方式将List转化为Tree 
     * @param listMap
     * @param root 
     * @return void
     * @author jc
     * @date 2023/6/20 13:26
     **/
    public static void list2TreeRecursion(Map<String, List<Tree2List>> listMap, Tree root) {

        List<Tree2List> list = listMap.get(root.getId());
        if (list == null) {
            return;
        }
        List<Tree> children = new ArrayList<>();
        for (Tree2List tree2 : list) {
            Tree tree = new Tree();
            tree.setId(tree2.getId());
            tree.setPid(tree2.getPid());
            tree.setName(tree2.getName());
            tree.setDesc(tree2.getDesc());
            children.add(tree);
            list2TreeRecursion(listMap, tree);
        }
        root.setChildren(children);

    }

    /**
     * description 初始化Tree
     * @return com.example.demo.Tree
     * @author jc
     * @date 2023/6/20 13:30
     **/
    public static Tree init() {

        Tree tree = new Tree("level0", "level0");

        Tree tree0_0 = new Tree("treeLevel0_0", "level1");
        Tree tree0_1 = new Tree("treeLevel0_1", "level1");
        List<Tree> children0 = new ArrayList<>();
        children0.add(tree0_0);
        children0.add(tree0_1);
        tree.setChildren(children0);

        Tree tree0_0_0 = new Tree("treeLevel0_0_0", "level2");
        Tree tree0_0_1 = new Tree("treeLevel0_0_1", "level2");
        Tree tree0_1_0 = new Tree("treeLevel0_1_0", "level2");
        Tree tree0_1_1 = new Tree("treeLevel0_1_1", "level2");

        List<Tree> children0_0 = new ArrayList<>();
        children0_0.add(tree0_0_0);
        children0_0.add(tree0_0_1);
        tree0_0.setChildren(children0_0);
        List<Tree> children0_1 = new ArrayList<>();
        children0_1.add(tree0_1_0);
        children0_1.add(tree0_1_1);
        tree0_1.setChildren(children0_1);

        Tree tree0_0_0_0 = new Tree("treeLevel0_0_0_0", "level3");
        Tree tree0_0_0_1 = new Tree("treeLevel0_0_0_1", "level3");
        Tree tree0_0_1_0 = new Tree("treeLevel0_0_1_0", "level3");
        Tree tree0_0_1_1 = new Tree("treeLevel0_0_1_1", "level3");
        Tree tree0_1_0_0 = new Tree("treeLevel0_1_0_0", "level3");
        Tree tree0_1_0_1 = new Tree("treeLevel0_1_0_1", "level3");
        Tree tree0_1_1_0 = new Tree("treeLevel0_1_1_0", "level3");
        Tree tree0_1_1_1 = new Tree("treeLevel0_1_1_1", "level3");

        List<Tree> children0_0_0 = new ArrayList<>();
        children0_0_0.add(tree0_0_0_0);
        children0_0_0.add(tree0_0_0_1);
        tree0_0_0.setChildren(children0_0_0);

        List<Tree> children0_0_1 = new ArrayList<>();
        children0_0_1.add(tree0_0_1_0);
        children0_0_1.add(tree0_0_1_1);
        tree0_0_1.setChildren(children0_0_1);

        List<Tree> children0_1_0 = new ArrayList<>();
        children0_1_0.add(tree0_1_0_0);
        children0_1_0.add(tree0_1_0_1);
        tree0_1_0.setChildren(children0_1_0);

        List<Tree> children0_1_1 = new ArrayList<>();
        children0_1_1.add(tree0_1_1_0);
        children0_1_1.add(tree0_1_1_1);
        tree0_1_1.setChildren(children0_1_1);

        return tree;

    }

    /**
     * description 获取递增的唯一ID
     * @return java.lang.Integer
     * @author jc
     * @date 2023/6/20 13:47
     **/
    public static Integer getIndex() {
        return index++;
    }

}

/**
 * Tree.java
 *
 * @author jc
 * @version 2023年06月15日 14:29
 */
class Tree implements Serializable {

    /** 临时pid */
    private transient String pid;
    /** 临时id */
    private transient String id;

    private String           name;

    private String           desc;

    private List<Tree>       children;

    public Tree() {
    }

    public Tree(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public Tree(String pid, String id, String name, String desc) {
        this.pid = pid;
        this.id = id;
        this.name = name;
        this.desc = desc;
    }

    /**
     * Gets the value of pid
     *
     * @return the value of pid
     */
    public String getPid() {
        return pid;
    }

    /**
     * Sets the pid
     *
     * @param pid pid
     */
    public void setPid(String pid) {
        this.pid = pid;
    }

    /**
     * Gets the value of id
     *
     * @return the value of id
     */
    public String getId() {
        return id;
    }

    /**
     * Sets the id
     *
     * @param id id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * Gets the value of name
     *
     * @return the value of name
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the name
     *
     * @param name name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Gets the value of desc
     *
     * @return the value of desc
     */
    public String getDesc() {
        return desc;
    }

    /**
     * Sets the desc
     *
     * @param desc desc
     */
    public void setDesc(String desc) {
        this.desc = desc;
    }

    /**
     * Gets the value of children
     *
     * @return the value of children
     */
    public List<Tree> getChildren() {
        return children;
    }

    /**
     * Sets the children
     *
     * @param children children
     */
    public void setChildren(List<Tree> children) {
        this.children = children;
    }

}

/**
 * Tree2List.java
 *
 * @author jc
 * @version 2023年06月15日 15:26 
 */
class Tree2List {

    private String pid;

    private String id;

    private String name;

    private String desc;

    /**
     * Gets the value of pid
     *
     * @return the value of pid
     */
    public String getPid() {
        return pid;
    }

    /**
     * Sets the pid
     *
     * @param pid pid
     */
    public void setPid(String pid) {
        this.pid = pid;
    }

    /**
     * Gets the value of id
     *
     * @return the value of id
     */
    public String getId() {
        return id;
    }

    /**
     * Sets the id
     *
     * @param id id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * Gets the value of name
     *
     * @return the value of name
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the name
     *
     * @param name name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Gets the value of desc
     *
     * @return the value of desc
     */
    public String getDesc() {
        return desc;
    }

    /**
     * Sets the desc
     *
     * @param desc desc
     */
    public void setDesc(String desc) {
        this.desc = desc;
    }
}

至此转化完成。

你可以使用递归的方式来将形结构转为list。具体来说,你可以先将根节点加入list中,然后递归处理每个子节点,并将它们加入list中。实现代码如下: ```java public List<TreeNode> flatten(TreeNode root) { List<TreeNode> result = new ArrayList<>(); flattenHelper(root, result); return result; } private void flattenHelper(TreeNode node, List<TreeNode> result) { result.add(node); for (TreeNode child : node.getChildren()) { flattenHelper(child, result); } } ``` 这里假设节点的定义如下: ```java public class TreeNode { private int val; private List<TreeNode> children; public TreeNode(int val) { this.val = val; children = new ArrayList<>(); } public void addChild(TreeNode child) { children.add(child); } public List<TreeNode> getChildren() { return children; } } ``` 如果你希望将形结构转为list的同时保留节点的层级信息,可以使用一个helper类来记录每个节点的层级: ```java public class FlattenedTreeNode { private TreeNode node; private int level; public FlattenedTreeNode(TreeNode node, int level) { this.node = node; this.level = level; } public TreeNode getNode() { return node; } public int getLevel() { return level; } } public List<FlattenedTreeNode> flatten(TreeNode root) { List<FlattenedTreeNode> result = new ArrayList<>(); flattenHelper(root, 0, result); return result; } private void flattenHelper(TreeNode node, int level, List<FlattenedTreeNode> result) { result.add(new FlattenedTreeNode(node, level)); for (TreeNode child : node.getChildren()) { flattenHelper(child, level + 1, result); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值