list列表转tree树方法(生成树型结构)

 基础类:

public class TreeNodeDto {
    private String id;
    private String parentId;
    /**
     * 节点名称
     */
    private String nodeName;
    private String nodeType;
    private String iconUrl;
    /**
     * 叶子节点业务id
     */
    private String businessId;
    /**
     * 节点排序号
     */
    private Integer treeSort = 0;
    private List<TreeNodeDto> childList;
}
View Code

 

list转tree递归转换

    /**
     * 递归遍历生成树结构
     * @param list
     * @param parentId
     * @return
     */
    public List<TreeNodeDto> findChildrenList(List<TreeNodeDto> list, String parentId) {
        List<TreeNodeDto> trees = new ArrayList<>();
        //获取到所有parentCode的子节点
        for (TreeNodeDto item : list) {
            if (parentId.equals(item.getParentId())) {
                trees.add(item);
                //递归遍历该子节点的子节点列表
                item.setChildList(this.findChildrenList(list, item.getParentId()));
            }
        }
        return trees;
    }

假设有列表有n个元素要组成一颗树,时间复杂度为O(n2), 每次递归都会创建一个treeList对象,空间复杂度为O(n)

 

这个递归可能当数据量太大时会造成方法栈内存溢出,不是很想使用这个方法。

双重for循环转tree

public class TreeNodeUtil {

    /**
     * 双重for循环 生成树结构
     * @param list
     * @param parentId
     * @return
     */
    public static List<TreeNodeDto> convertTree(List<TreeNodeDto> list, String parentId) {
        List<TreeNodeDto> trees = new ArrayList<>();
        for (TreeNodeDto item : list) {
            //只将根节点添加到trees树的根中
            if (parentId.equals(item.getParentId())) {
                trees.add(item);
            }

            // 查询当前节点的所有子节点,设置到当前节点下
            for (TreeNodeDto childItem : list) {
                // 父节点id和外层循环的节点id相等,表示归属于外层循环节点的子节点,加入到列表
                if (item.getId().equals(childItem.getParentId())) {
                    if (item.getChildList() == null) {
                        item.setChildList(new ArrayList<TreeNodeDto>());
                    }
                    item.getChildList().add(childItem);
                }
            }
        }
        return trees;
    }
}

上面双重for循环,

最外层循环的作用是:

1、过滤获取指定父节点下根节点作为一颗树列表的根节点。(树列表只存储根节点,其他分支都是根节点上追加)
2、还有一个作用是,遍历所有节点的子节点列表

第二层for循环就是用来查找节点的字节点。

 

还有一种,使用Map<id, object>存放id 和对象本身。查询父节点id时,直接map.get( parentID)获取父节点对象,追加到父节点的childList中。

/**
     * Map存放key值进行转换
     * @param list
     * @param parentId
     * @return
     */
    public List<TreeNodeDto> convertTreeUseMap(List<TreeNodeDto> list, String parentId) {
        Map<String, TreeNodeDto> mapData = new HashMap<>();
        List<TreeNodeDto> rootData = new ArrayList<>();
        for (TreeNodeDto item : list) {
            // 全部放入map中
            if (item.getParentId().equals(parentId)) {
                rootData.add(item);
            }
            mapData.put(item.getId(), item);
        }

        for (TreeNodeDto item : list) {
            // 一次性把所有列表组合成树
            String tmpParentId = item.getParentId();
            // 排除根节点
            if (tmpParentId.equals(parentId)) {
                continue;
            }
            TreeNodeDto parent = mapData.get(tmpParentId);
            if (parent.getChildList() == null) {
                parent.setChildList(new ArrayList<>());
            }
            parent.getChildList().add(item);
        }
        return rootData;
    }
View Code

 

 

可能还会有需求时,树结构要按照排序号进行同级节点的排序,可以递归获取字列表,或者for循环获取字列表后进行list排序

 

参考资料

java list 转树 tree 的三种写法:https://blog.csdn.net/jcroad/article/details/79735790#commentBox

posted @ 2019-11-19 15:09  海绵般汲取  阅读(11494)  评论(0编辑  收藏  举报