将List数据转成树的两种方式(递归、循环)

在做用户菜单权限的时候(因为多张表关联外键,hibernate返回回去会出现无限循环),所以把他转换成和数据库无关的VO类即可

一 、VO类如下

**
 *
 *
 * 封装菜单的树形结构
 * @author 六松岛福小林
 *
 **/
public class MenuTree implements java.io.Serializable  {
    /**
     * 树形节点id
     */
    private String id;

    /**
     * 菜单级别 0为第一级菜单,1为第二级菜单……
     */
    private  String  level;
    /**
     * 父级树形id
     */
    private String parentId;

    /**
     * 树形节点名称
     */
    private String name;

    /**
     * 对应的菜单图片路径
     */

    private  String imagePath;

    /**
     * 菜单对应的url地址
     */
    private String url;

    /**
     * 子节点list
     */
    private List<MenuTree> children;

	……对应的Getter和Setter 这个在此省略……

}

二、封装的树形工具类如下
备注:循环和递归使用任何一种即可

  /**
     * 两层循环实现建树
     * @param menuTrees 传入的树节点列表
     * @return List<MenuTree> 子节点集合
     */
    public static List<MenuTree> build(List<MenuTree> menuTrees) {
            //返回的树形结构数据
        List<MenuTree> trees = new ArrayList<>();
        //循环菜单树形数据
        for (MenuTree menuTree : menuTrees) {
            //菜单级别为0,则是一级数据,根据实际情况判断可修改相关关联判断
            if("0".equals(menuTree.getLevel())){
                trees.add(menuTree);
                for (MenuTree it : menuTrees) {
                    //找出一级菜单下面的所有二级菜单,并加入到list中去
                    if (menuTree.getId().equals(it.getParentId())) {
                        if (menuTree.getChildren() == null) {
                            menuTree.setChildren(new ArrayList<MenuTree>());
                        }
                        menuTree.getChildren().add(it);
                    }
                }
            }
        }
        return trees;
    }

    /**
     * 使用递归方法建树
     * @param menuTrees  子节点集合
     * @return List<MenuTree>
     */
    public static List<MenuTree> buildByRecursive(List<MenuTree> menuTrees) {
        List<MenuTree> trees = new ArrayList<>();
        for (MenuTree menuTree : menuTrees) {
           //菜单级别为0,则是一级数据,根据实际情况判断可修改相关关联判断
            if ("0".equals(menuTree.getLevel())) {
                trees.add(findChildren(menuTree,menuTrees));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     * @param menuTree  菜单数对象
     * @param menuTrees  子节点
     * @return MenuTree
     */
    private static MenuTree findChildren(MenuTree menuTree,List<MenuTree> menuTrees) {
        for (MenuTree it : menuTrees) {
            if(menuTree.getId().equals(it.getParentId())) {
                if (menuTree.getChildren() == null) {
                    menuTree.setChildren(new ArrayList<MenuTree>());
                }
                menuTree.getChildren().add(findChildren(it,menuTrees));
            }
        }
        return menuTree;
    }

三、调用


    /**
     *根据用户id返回菜单的树形数据
     * @param userId  用户的id
     * @param systemService 操作数据库的service
     * @return 封装好的菜单树形数据
     */
    public  static List<MenuTree> getMenuTreeList(String userId, SystemService systemService) throws Exception{
            //查询该用户所有的菜单数据
            List<Map<String, Object>> menuDataList = getMenuDataList(userId, systemService);
            //封装成菜单对象list
            List<MenuTree> menuList = getMenuList(menuDataList);
            //调用封装树形数据方法
            return TreeBuilder.build(menuList);

    }

仍在不断学习中,如有不妥还望各位大神留言指教

代码下载地址 在下一篇根据用户查询相关菜单的博客中

List数据转换成形结构的基本思路是首先遍历List,将其中每个节点的父子关系建立起来,然后从根节点开始递归构建整个形结构。 具体实现步骤如下: 1. 定义节点,包含节点id、节点名称和子节点列表等属性。 ``` public class TreeNode { private String id; private String name; private List<TreeNode> children; // getter和setter方法 // ... } ``` 2. 遍历List,将每个节点的父子关系建立起来,可以使用Map来存储节点id和对应的节点对象,便于查找父节点。 ``` Map<String, TreeNode> map = new HashMap<>(); for (TreeNode node : list) { map.put(node.getId(), node); String parentId = node.getParentId(); if (parentId != null) { TreeNode parent = map.get(parentId); if (parent != null) { parent.getChildren().add(node); } } } ``` 3. 找到根节点,开始递归构建整个形结构。 ``` public static TreeNode buildTree(List<TreeNode> list) { // 构建Map,方便查找节点 Map<String, TreeNode> map = new HashMap<>(); for (TreeNode node : list) { map.put(node.getId(), node); } // 找到根节点 TreeNode root = null; for (TreeNode node : list) { if (node.getParentId() == null) { root = node; break; } } // 从根节点开始递归构建整个形结构 buildSubTree(root, map); return root; } private static void buildSubTree(TreeNode node, Map<String, TreeNode> map) { List<TreeNode> children = node.getChildren(); if (children == null) { return; } // 遍历子节点,递归构建子 for (TreeNode child : children) { buildSubTree(child, map); } // 根据子节点的顺序重新排序 children.sort(Comparator.comparing(TreeNode::getName)); } ``` 以上就是将List数据转换成行结构的基本实现方法。需要注意的是,这里的代码只是一个简单的示例,实际情况下可能需要根据具体的业务需求进行修改和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值