随笔(九)『Java 将list构建为tree(简单demo)』

1、表数据

2、实体类

/**
 * <p>
 * 菜单表
 * </p>
 *
 * @author baihua
 * @since 2022-12-09
 */
@Data
@TableName("sys_menu")
@ApiModel(value = "Menu对象", description = "菜单表")
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("ID")
    private Long id;

    @ApiModelProperty("父级ID,一级菜单为0")
    private Long pid;

    @ApiModelProperty("菜单名称")
    private String name;

    @ApiModelProperty("菜单URL")
    private String url;

    @ApiModelProperty("授权(多个用逗号隔开,如:sys:user:save)")
    private String permissions;

    @ApiModelProperty("类型(0-菜单,1-按钮)")
    private Boolean type;

    @ApiModelProperty("图标")
    private String icon;

    @ApiModelProperty("排序")
    private Integer sort;

    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    private Date createDate;

    @ApiModelProperty("子菜单列表")
    @TableField(exist = false)
    private List<Menu> children = new ArrayList<>();
}

3、controller层

    // 获取所有的菜单列表(以树的形式)
    @GetMapping("getMenuListTree")
    public Result getMenuListTree() {
        return memuService.getMenuListTree();
    }

4、service层

Result getMenuListTree();

5、service实现类

    @Override
    public Result getMenuListTree() {
        // 从数据库获取所有的数据
        List<Menu> menuList = baseMapper.selectList(null);

        // 将数据转为树
        List<Menu> menuListTree = buildTree(menuList);

        return Result.success(menuListTree);
    }

    /**
     *
     * 1、先找到所有的顶级节点(即一级节点)
     * 2、递归查找子节点
     *
     * @param treeNodes 所有的节点,即所有的菜单
     * @return
     */
    private List<Menu> buildTree(List<Menu> treeNodes) {
        List<Menu> listTree = new ArrayList<>();
        Long pid = 0L; // 一级菜单的父id
        for (Menu treeNode : treeNodes) {
            // 判断是否为一级菜单,如果是一级菜单就查找子级菜单
            if (pid.equals(treeNode.getPid())) {
                Menu menu = findChildren(treeNodes, treeNode); // 查找子菜单
                listTree.add(menu);
            }
        }

        return listTree;
    }

    /**
     *  递归查找子菜单
     * @param treeNodes 所有的节点,即所有的菜单
     * @param rootNode 当前根节点
     * @return
     */
    private Menu findChildren(List<Menu> treeNodes, Menu rootNode) {
        for (Menu treeNode : treeNodes) {
            /**
             * 判断当前节点的父节点id,是否为此根节点的id
             * 是代表:当前节点是此根节点的小孩(子节点)
             */
            if (rootNode.getId().equals(treeNode.getPid())) {
                // 查找子节点是否还存在子节点
                rootNode.getChildren().add(findChildren(treeNodes, treeNode));
            }
        }

        return rootNode;
    }

6、测试

posted @   小昕昕  阅读(152)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示