java后端操作树结构的案例代码

 更新时间:2023年10月24日 08:53:41   作者:spiderMan1-1  
这篇文章主要介绍了java后端操作树结构,树结构的三种组装方式(递归.双层for循环,map),通过实例代码介绍了使用递归查询某个节点所在的树结构,需要的朋友可以参考下

一、树结构的三种组装方式(递归.双层for循环,map)

(1)递归

普通递归方法

 public Result getBmsMenuList(UserSessionVO userSessionInfo) {
        // 查询顶级节点菜单
        List<BmsMenuVO> bmsMenuVOList = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO());

        for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
            getBmsMenuListByRecursion(bmsMenuVO);
        }

        return Result.createWithModels(null, bmsMenuVOList);
    }

 private void getBmsMenuListByRecursion(BmsMenuVO bmsMenuVO) {
        List<BmsMenuVO> bmsMenuVOS = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO().setParentId(bmsMenuVO.getId()));
        if (CollectionUtils.isEmpty(bmsMenuVOS)) {
            return;
        }
        bmsMenuVO.setChildBmsMenuList(bmsMenuVOS);
        for (BmsMenuVO menuVO : bmsMenuVOS) {
            getBmsMenuListByRecursion(menuVO);
        }
}

stream流递归方法

//获取父节点
List<TreeSelect> collect = trees.stream().filter(m -> m.getParentId() == 0).map(
    (m) -> {
        m.setChildren(getChildrenList(m, trees));
        return m;
    }
).collect(Collectors.toList());
 
    /**
     * 获取子节点列表
     * @param tree
     * @param list
     * @return
     */
    public static List<TreeSelect> getChildrenList(TreeSelect tree, List<TreeSelect> list){
        List<TreeSelect> children = list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).map(
                (item) -> {
                    item.setChildren(getChildrenList(item, list));
                    return item;
                }
        ).collect(Collectors.toList());
        return children;
    }

(2)双层for循环

// 查询主节点
List<BmsMenuVO> bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);

// 拼装结果
 List<BmsMenuVO> bmsMenuTree = new ArrayList<>();
 for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
      // 根节点的父Id为null
      if (bmsMenuVO.getParentId() == null) {
                bmsMenuTree.add(bmsMenuVO);
      }
      for (BmsMenuVO menuVO : bmsMenuVOList) {
           if (menuVO.getParentId() != null && menuVO.getParentId().equals(bmsMenuVO.getId())) {
               if (CollectionUtils.isEmpty(bmsMenuVO.getChildBmsMenuList())) {
                        bmsMenuVO.setChildBmsMenuList(new ArrayList<>());
                }
                bmsMenuVO.getChildBmsMenuList().add(menuVO);
           }
       }
  }

  // 返回结果
 return Result.createWithModels(null, bmsMenuTree);

(3)map遍历

 // 查询所有节点
 List<BmsMenuVO> bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
       
 // 拼装结果     
 List<BmsMenuVO> bmsMenuTree = new ArrayList<>();
 // 用来存储节点的子元素map
 Map<Long, BmsMenuVO> childBmsMenuMap = new LinkedHashMap<>();
        for (BmsMenuVO menuVO : bmsMenuVOList) {
            childBmsMenuMap.put(menuVO.getId(), menuVO);
        }
        for (Long bmsMenuId : childBmsMenuMap.keySet()) {
            BmsMenuVO menuVO = childBmsMenuMap.get(bmsMenuId);
            Long parentId = menuVO.getParentId();
            if (parentId == null) {
                bmsMenuTree.add(menuVO);
            } else {
                BmsMenuVO parentMenuVO = childBmsMenuMap.get(parentId);
                if (parentMenuVO.getChildBmsMenuList() == null) {
                    parentMenuVO.setChildBmsMenuList(new ArrayList<>());
                }
                parentMenuVO.getChildBmsMenuList().add(menuVO);
          }
} 

2、使用递归查询某个节点所在的树结构

使用场景:当我们得到一个树形结构数据时,可能需要在树形结构上对数据进行筛选,例如通过文件夹(文件)名称模糊查询相关的文件夹并展现其父级。

缺点:需要查询出完整的树形结构才能用作筛选,在数据量非常庞大的时候并不适用。

@Data
public class TreeDto {

   private String id;
   private String name;
   private List<TreeDto> subsetTreeDtoList;



   public TreeDto(String id,String name,List<TreeDto> subsetTreeDtoList){
       this.id = id;
       this.name = name;
       this.subsetTreeDtoList = subsetTreeDtoList;
   }
}

筛选

  /**
    * 树形筛选查找
    * @param treeDtoList 树形集合
    * @param idList 筛选条件(可以是其他条件)
    * @return 包含的节点数据
    */
   public static List<TreeDto> screenTree(List<TreeDto> treeDtoList, List<String> idList){
       //最后返回的筛选完成的集合
       List<TreeDto> screeningOfCompleteList = new ArrayList<>();
       if (listIsNotEmpty(treeDtoList) && listIsNotEmpty(idList)){
           for (TreeDto treeDto : treeDtoList){
               List<TreeDto> subsetList = treeDto.getSubsetTreeDtoList();
               //递归筛选完成后的返回的需要添加的数据
               TreeDto addTreeDto = getSubsetPmsPlanPo(treeDto,subsetList,idList);
               if (isNotEmpty(addTreeDto)){
                   screeningOfCompleteList.add(addTreeDto);
               }
           }
           return screeningOfCompleteList;
       }
       return null;
   }


   /**
    * 筛选符合的集合并返回
    * @param treeDto 树形类
    * @param subsetTreeDtoList 子集集合
    * @param idList 筛选条件
    * @return 筛选成功的类
    */
   public static TreeDto getSubsetPmsPlanPo(TreeDto treeDto,List<TreeDto> subsetTreeDtoList,List<String> idList){
       //作为筛选条件的判断值
       String id = treeDto.getId();
       //有子集时继续向下寻找
       if (listIsNotEmpty(subsetTreeDtoList)){
           List<TreeDto> addTreeDtoList = new ArrayList<>();
           for (TreeDto subsetTreeDto : subsetTreeDtoList){
               List<TreeDto> subsetList = subsetTreeDto.getSubsetTreeDtoList();
               TreeDto newTreeDto = getSubsetPmsPlanPo(subsetTreeDto,subsetList,idList);
               //当子集筛选完不为空时添加
               if (isNotEmpty(newTreeDto)){
                   addTreeDtoList.add(newTreeDto);
               }
           }
           //子集满足条件筛选时集合不为空时,替换对象集合内容并返回当前对象
           if (listIsNotEmpty(addTreeDtoList)){
               treeDto.setSubsetTreeDtoList(addTreeDtoList);
               return treeDto;
               //当前对象子集对象不满足条件时,判断当前对象自己是否满足筛选条件,满足设置子集集合为空,并返回当前对象
           }else if (listIsEmpty(addTreeDtoList) && idList.contains(id)){
               treeDto.setSubsetTreeDtoList(null);
               return treeDto;
           }else {
               //未满足筛选条件直接返回null
               return null;
           }
       }else {
           //无子集时判断当前对象是否满足筛选条件
           if (idList.contains(id)){
               return treeDto;
           }else {
               return null;
           }
       }
   }

   /**
    * 判断集合为空
    * @param list 需要判断的集合
    * @return 集合为空时返回 true
    */
   public static boolean listIsEmpty(Collection list){
       return  (null == list || list.size() == 0);
   }

   /**
    * 判断集合非空
    * @param list 需要判断的集合
    * @return 集合非空时返回 true
    */
   public static boolean listIsNotEmpty(Collection list){
       return !listIsEmpty(list);
   }

   /**
    * 判断对象为null或空时
    * @param object 对象
    * @return 对象为空或null时返回 true
    */
   public static boolean isEmpty(Object object) {
       if (object == null) {
           return (true);
       }
       if ("".equals(object)) {
           return (true);
       }
       if ("null".equals(object)) {
           return (true);
       }
       return (false);
   }

   /**
    * 判断对象非空
    * @param object 对象
    * @return 对象为非空时返回 true
    */
   public static boolean isNotEmpty(Object object) {
       if (object != null && !object.equals("") && !object.equals("null")) {
           return (true);
       }
       return (false);
   }

   public static void main(String[] args) {
       TreeDto treeDto1 = new TreeDto("1","A",new ArrayList<TreeDto>());
       TreeDto treeDto1_1 = new TreeDto("1.1","A-A",new ArrayList<TreeDto>());
       TreeDto treeDto1_2 = new TreeDto("1.2","A-B",new ArrayList<TreeDto>());
       TreeDto treeDto1_3 = new TreeDto("1.3","A-C",new ArrayList<TreeDto>());
       treeDto1.getSubsetTreeDtoList().add(treeDto1_1);
       treeDto1.getSubsetTreeDtoList().add(treeDto1_2);
       treeDto1.getSubsetTreeDtoList().add(treeDto1_3);

       TreeDto treeDto2 = new TreeDto("2","B",new ArrayList<TreeDto>());
       TreeDto treeDto2_1 = new TreeDto("2.1","B-A",new ArrayList<TreeDto>());
       TreeDto treeDto2_2 = new TreeDto("2.2","B-B",new ArrayList<TreeDto>());
       TreeDto treeDto2_3 = new TreeDto("2.3","B-C",new ArrayList<TreeDto>());
       TreeDto treeDto2_3_1 = new TreeDto("2.3.1","B-C-A",null);
       treeDto2.getSubsetTreeDtoList().add(treeDto2_1);
       treeDto2.getSubsetTreeDtoList().add(treeDto2_2);
       treeDto2.getSubsetTreeDtoList().add(treeDto2_3);
       treeDto2.getSubsetTreeDtoList().get(2).getSubsetTreeDtoList().add(treeDto2_3_1);

       String[] array = {"1.3","2.2","2.3.1"};
       List<String> idList = Arrays.asList(array);
       List<TreeDto> treeDtoList = new ArrayList<>();
       treeDtoList.add(treeDto1);
       treeDtoList.add(treeDto2);
       System.out.println(JSON.toJSONString(screenTree(treeDtoList,idList)));
   }
}

返回结果为

到此这篇关于java后端操作树结构的文章就介绍到这了,更多相关java树结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java web开发中加载图片路径的两种方式

    Java web开发中加载图片路径的两种方式

    下文给大家介绍基于编译器idea以及tomcat服务器开发的,对Java web开发加载图片路径的两种方式感兴趣的朋友一起看看吧
    2017-07-07
  • Maven install 报错

    Maven install 报错"程序包不存在"问题的解决方法

    这篇文章主要介绍了Maven install 报错"程序包不存在"问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • springboot 实现mqtt物联网的示例代码

    springboot 实现mqtt物联网的示例代码

    这篇文章主要介绍了springboot 实现mqtt物联网,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • mybatis的动态sql之if test的使用说明

    mybatis的动态sql之if test的使用说明

    这篇文章主要介绍了mybatis的动态sql之if test的使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java实战之酒店人事管理系统的实现

    Java实战之酒店人事管理系统的实现

    这篇文章主要介绍了如何用Java实现酒店人事管理系统,文中采用的技术有:JSP、Spring、SpringMVC、MyBatis等,感兴趣的小伙伴可以学习一下
    2022-03-03
  • Java高并发BlockingQueue重要的实现类详解

    Java高并发BlockingQueue重要的实现类详解

    这篇文章主要给大家介绍了关于Java高并发BlockingQueue重要的实现类的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 基于springBoot配置文件properties和yml中数组的写法

    基于springBoot配置文件properties和yml中数组的写法

    这篇文章主要介绍了springBoot配置文件properties和yml中数组的写法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java平闰年判断的方法总结

    Java平闰年判断的方法总结

    本篇文章给大家整理了Java平闰年判断的两种方法,大家在写程序的时候如果用的到参考下吧。
    2018-02-02
  • Java使用正则获取括号里面的内容

    Java使用正则获取括号里面的内容

    这篇文章主要介绍了Java使用正则获取括号里面的内容问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 学会Pulsar Consumer的使用方式

    学会Pulsar Consumer的使用方式

    这篇文章主要介绍了Pulsar Consumer的使用方式,全文使用大量的代码来做了详细的讲解,感兴趣的小伙伴可以参考一下这篇文章,希望读完能对你有很大的帮助
    2021-08-08

最新评论