Java List与树的互转

摘要:
  TreeNode@Data@JsonInclude(JsonInclusive.NON_NULL)publicclassTreeNode<儿童privatebooleanhasChildren=false;trees=newArrayList<list){list.forEach(实体->树=newTreeNode<
  平时工作中都会遇到包含层级关系的List数据转换成树形结构,或者数据已是树形结构了,需要我们处理成普通的单层list结构。以下代码均为本人实际开发所写代码,可能不是最优解、复杂度也比较高,在此和大家一起分享学习!
  注:该工具类支持将list转换成树/森林。可自行测试,有疑问或更优方案,可私聊我。
 
  TreeNode
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TreeNode<T> {

    private String id;

    private String key;

    private String value;

   private String name; private String parentId; private String createName; private LocalDateTime createTime; private List<TreeNode<T>> children; private boolean hasParent = false; private boolean hasChildren = false; public void initChildren() { this.children = new ArrayList<>(); } }
TreeUtil
public class TreeUtil {

    protected TreeUtil() {

    }

    private final static String TOP_NODE_ID = "0";



    /**
     * 使用递归方法建树
     *
     * @param nodes
     * @return
     */
    public static List<TreeNode<T>> buildByRecursive(List<TreeNode<T>> nodes) {
        List<TreeNode<T>> trees = new ArrayList<>();
        for (TreeNode<T> treeNode : nodes) {
            if (TOP_NODE_ID.equals(treeNode.getParentId())) {
                trees.add(findChildren(treeNode,nodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    public static TreeNode<T> findChildren(TreeNode<T> treeNode, List<TreeNode<T>> treeNodes) {
        for (TreeNode<T> it : treeNodes) {
            if (treeNode.getId().equals(it.getParentId())) {
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<TreeNode<T>>());
                }
                treeNode.getChildren().add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    public static void buildTrees(List<TreeNode<T>> trees, List<T> list) {
        list.forEach(entity -> {
            TreeNode<T> tree = new TreeNode<>();
            tree.setId(entity.getId());
            tree.setKey(entity.getId());
            tree.setValue(entity.getId());
            tree.setName(entity.getName());
            tree.setParentId(entity.getParentId());
            tree.setCreateTime(entity.getCreateTime());
            tree.setCreateName(entity.getCreateName());
            trees.add(tree);
        });
    }

    public static <T> List<TreeNode<T>> buildTreeList(List<TreeNode<T>> nodes) {
        if (nodes == null) {
            return null;
        }
        List<TreeNode<T>> topNodes = new ArrayList<>();
        //利用两层循环,组装树/森林结构
        nodes.forEach(first -> {
            String pid = first.getParentId();
            first.setHasParent(true);
            if (pid == null || TOP_NODE_ID.equals(pid)) {
                topNodes.add(first);
                first.setHasParent(false);
            } else {
                boolean isExistPid = false;
                for (TreeNode<T> temp : nodes) {
                    if (temp.getId().equals(pid)) {
                        isExistPid = true;
                    }
                }
                if (!isExistPid) {
                    topNodes.add(first);
                    first.setHasParent(false);
                }
            }
            for (TreeNode<T> second : nodes) {
                String id = second.getId();
                if (id != null && id.equals(pid)) {
                    if (second.getChildren() == null) {
                        second.initChildren();
                    }
                    second.getChildren().add(first);
                    first.setHasParent(true);
                    second.setHasChildren(true);
                    second.setHasParent(true);
                    return;
                }
            }
        });
        return topNodes;
    }

    public static <T> TreeNode<T> buildTree(List<TreeNode<T>> nodes) {
        if (nodes == null) {
            return null;
        }
        List<TreeNode<T>> topNodes = new ArrayList<>();
        //利用两层循环,组装树/森林结构
        nodes.forEach(first -> {
            String pid = first.getParentId();
            first.setHasParent(true);
            if (pid == null || TOP_NODE_ID.equals(pid)) {
                topNodes.add(first);
                first.setHasParent(false);
            } else {
                boolean isExistPid = false;
                for (TreeNode<T> temp : nodes) {
                    if (temp.getId().equals(pid)) {
                        isExistPid = true;
                    }
                }
                if (!isExistPid) {
                    topNodes.add(first);
                    first.setHasParent(false);
                }
            }
            for (TreeNode<T> second : nodes) {
                String id = second.getId();
                if (id != null && id.equals(pid)) {
                    if (second.getChildren() == null) {
                        second.initChildren();
                    }
                    second.getChildren().add(first);
                    first.setHasParent(true);
                    second.setHasChildren(true);
                    second.setHasParent(true);
                    return;
                }
            }
        });
        TreeNode<T> root = new TreeNode<>();
        root.setId("0");
        root.setParentId("");
        root.setHasParent(false);
        root.setHasChildren(true);
        root.setChildren(topNodes);
        root.setName("root");
        return root;
    }


    public static <T> List<TreeNode<T>> tree2List(List<TreeNode<T>>  treeList) {
        List<TreeNode<T>> list = new ArrayList<>();
        for (TreeNode<T> tree : treeList) {
            List<TreeNode<T>> child = tree.getChildren();
            list.add(tree);
            if (child != null && child.size() > 0) {
                list.addAll(tree2List(child));
                tree.setChildren(null);
            }
        }
        return list;
    }
}

免责声明:文章转载自《Java List与树的互转》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Openjudge-NOI题库-对齐输出Delphi连接Oracle控件ODAC的安装及使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android开发 Html工具类详解

前言  在一些需求富文本显示或者编辑的开发情况下,数据都是用html的格式来保存文本信息的.而google是有提供解析html的工具类那就是Html.有了Html可以让TextView也支持富文本(其实原理还是解析Html然后在转成SpannableString再给TextView显示) 显示Html格式文本 String htmlConte...

HSF服务的开发与使用

转载:http://www.cnblogs.com/cloudml/p/4675705.html#undefined 1.HSF服务的开发 1) 基于Maven创建一个web工程HSFService,如下图,其他的可以自定义。 2)创建好好在src/main目录下创建一个java目录,并将其设置为sources folder,如下图所示: 3) 配置项...

Android View的Adapter

1 Adapter适配的对象是View Adapter通过为View提供指定格式的数据来适配View,让View可以以事先约定好的方式将内容展示给用户。 所以,进行UI设计的关键是搞清楚各个View组件的外观以及它们需要的数据的格式,然后选用合适的Adapter交给它们即可。 2 观察者模式在Android Adapter中的应用  所谓的观察者就是说,让...

说说C#中IList与List区别

我知道IList是一个接口,而List可以实例化IList。请问,我不可以不定义接口IList么?或者在IDAL(接口中)定义List吗?必须是Ilist么??请大家谈谈他们之间的区别和作用? (摘自网络)   首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口。 它仅仅是所有泛型类型的接口,并没有太多方...

QTablewidget通过代理实现限制输入

QTablewidget代理 之前做过一个QTablewidget想要限制某些单元格只能输入IP,刚开始采用在单元格中添加QLineEdit控件的方法,效果差强人意。后来发现通过QItemDelegate可以很方便实现需求。 QItemDelegate  1 #pragma once 2 #include <QWidget> 3 #inc...

Mac版sublime text右键open in browser 不能识别中文名解决办法

问题描述: Mac下sublime text下打开中文命名的html文件,右键open in browser,浏览器无反应。 解决思路: 要么适应软件,要么改进软件来适应。 1.  将中文名的html文件,改成英文名的html文件来预览。 2.  改造sublime text, 安装插件SideBarEnhancements,使用插件的“open in...