java8递归遍历树形结构

java8递归遍历树形结构

  1. 菜单实体类
@Data 
public class Menu {
    //id
    private String id;

    //菜单名
    private String name;

    //父节点id
    private String pid;

    //子节点信息
    private List<Menu> children;

	//无参构造
    public Menu() {}
    
    //带参构造
    public Menu(String id, String name, String pid) {
        this.id = id;
        this.name = name;
        this.pid= pid;
    }
}
  1. 递归遍历树形结构(含有多个根节点)
public void getTreeMenu() {
    //模拟数据库查出所有数据
    List<Menu> menus = Arrays.asList(
        new Menu(1, "根节点", 0),
        new Menu(2, "子节点1", 1),
        new Menu(3, "子子节点1.1", 2),
        new Menu(6, "子子子节点1.1.1", 3),
        new Menu(4, "子节点2", 1),
        new Menu(5, "子子节点2.1", 4),
        new Menu(6, "根节点2", 0),
        new Menu(7, "子节点1", 6),
        new Menu(8, "子子节点1.1", 7),
    );

    //筛选出根节点
    List<Menu> list = menus.stream().filter(menu -> "0".equals(menu.getPid())).peek(
        //设置子节点信息
        menu -> menu.setChildren(getChildrenList(menu, menus))
    ).collect(Collectors.toList());
}

private List<Menu> getChildrenList(Menu root, List<Menu> menus) {
    List<Menu> list = menus.stream().filter(menu ->
                                            //筛选出下一节点元素
                                            Objects.equals(menu.getPid(), root.getId())).map(menu -> {
        //递归set子节点
        menu.setChildren(this.getChildrenList(menu, menus));
        return menu;
    }).collect(Collectors.toList());	
    return list;
}
  1. 递归遍历树形结构(单个根节点)
public void getTreeMenu() {
    //模拟数据库查出所有数据
    List<Menu> menus = Arrays.asList(
        new Menu(1, "根节点", 0),
        new Menu(2, "子节点1", 1),
        new Menu(3, "子子节点1.1", 2),
        new Menu(6, "子子子节点1.1.1", 3),
        new Menu(4, "子节点2", 1),
        new Menu(5, "子子节点2.1", 4)
    );

    //筛选出根节点
    List<Menu> list = menus.stream().filter(menu -> "0".equals(menu.getPid())).peek(
        //设置子节点信息
        menu -> menu.setChildren(getChildrenList(menu, menus))
    ).findFirst().orElse(new Menu());
}

private List<Menu> getChildrenList(Menu root, List<Menu> menus) {
    List<Menu> list = menus.stream().filter(menu ->
                                            //筛选出下一节点元素
                                            Objects.equals(menu.getPid(), root.getId())).map(menu -> {
        //递归set子节点
        menu.setChildren(this.getChildrenList(menu, menus));
        return menu;
    }).collect(Collectors.toList());	
    return list;
}
  1. 递归删除节点及其子节点(结合MybatisPlus框架)
public void deleteMenus(String id) {
    //存储所有要删除的id
    List<String> idList = new ArrayList<>();
    //获得所有需要删除的id
    this.selectChildListById(id, idList);
    //添加删除的节点id
    idList.add(id);
    //MybatisPlus批量删除方法
    baseMapper.deleteBatchIds(idList);
}

private String selectChildListById(String id, List<String> idList) {
    //查询数据库pid等于id的数据
    List<Menu> childList = baseMapper.selectList(new QueryWrapper<Menu>().eq("pid", id).select("id"));
    //递归查询下一级id,同时将上一次查询结果添加到list集合
    childList.forEach(menu-> {
        idList.add(menu.getId());
        this.selectChildListById(menu.getId(), idList);
    });
}
/** * 根据等级查询类目树 * * @param level * @return */ @Override public List queryCategoryTree(Integer level) { //查询当前级别下类目 List list = categoryDAO.list(level); //组装好的类目树,返回前端 List categoryTree = new ArrayList(); //所有类目 List allDTOList = new ArrayList(); if (CollectionUtils.isEmpty(list)) { return categoryTree; } for (CategoryDO categoryDO : list) { allDTOList.add(new CategoryTreeDTO().convertDOToDTO(categoryDO)); } //当前等级类目 categoryTree = allDTOList.stream().filter(dto -> level.equals(dto.getLevel())).collect(Collectors.toList()); for (CategoryTreeDTO categoryTreeDTO : categoryTree) { //组装类目为树结构 assembleTree(categoryTreeDTO, allDTOList,Constants.CATEGORY_MAX_LEVEL - level); } return categoryTree; } /** * 组装树 * * @param categoryTreeDTO * @param allList * @param remainRecursionCount 剩余递归次数 * @return */ public CategoryTreeDTO assembleTree(CategoryTreeDTO categoryTreeDTO, List allList, int remainRecursionCount) { remainRecursionCount--; //最大递归次数不超过Constants.CATEGORY_MAX_LEVEL-level次,防止坏数据死循环 if(remainRecursionCount < 0){ return categoryTreeDTO; } String categoryCode = categoryTreeDTO.getCategoryCode(); Integer level = categoryTreeDTO.getLevel(); //到达最后等级树返回 if (Constants.CATEGORY_MAX_LEVEL == level) { return categoryTreeDTO; } //子类目 List child = allList.stream().filter(a -> categoryCode.equals(a.getParentCode())).collect(Collectors.toList()); if (null == child) { return categoryTreeDTO; } categoryTreeDTO.setChildren(child); //组装子类目 for (CategoryTreeDTO dto : child) { assembleTree(dto, allList,remainRecursionCount); } return categoryTreeDTO; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值