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中Lambda表达式的进化之路详解

    Java中Lambda表达式的进化之路详解

    本文通过示例大家给大家介绍了Java中Lambda表达式的进化之路,感兴趣的的朋友一起看看吧,希望能够给你带来帮助
    2021-11-11
  • Java中Integer两种转int方法比较

    Java中Integer两种转int方法比较

    本文主要介绍了Java Integer两种转int方法比较。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • SpringBoot整合liquibase的实现方法

    SpringBoot整合liquibase的实现方法

    这篇文章主要介绍了SpringBoot整合liquibase的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java中的springboot监听事件和处理事件详解

    Java中的springboot监听事件和处理事件详解

    这篇文章主要介绍了Java中的springboot监听事件和处理事件,这个示例展示了如何在Spring Boot应用中定义自定义事件、发布事件以及监听事件,需要的朋友可以参考下
    2024-07-07
  • 新版本Spring中lombok失效的问题解决

    新版本Spring中lombok失效的问题解决

    Lombok是一个Java库,通过添加注解简化代码编写,本文主要介绍了新版本Spring中lombok失效的问题解决,感兴趣的可以了解一下
    2025-01-01
  • SpringBoot Bean花式注解方法示例下篇

    SpringBoot Bean花式注解方法示例下篇

    这篇文章主要介绍了SpringBoot Bean花式注解方法,很多时候我们需要根据不同的条件在容器中加载不同的Bean,或者根据不同的条件来选择是否在容器中加载某个Bean
    2023-02-02
  • Java中Lombok常用注解分享

    Java中Lombok常用注解分享

    以前的Java项目中充斥了太多不友好的代码,这些代码不仅没有什么技术含量,还影响代码的美观,所以Lombok应运而生了。本文和大家分享了一些Java中Lombok常用注解,需要的可以了解一下
    2023-04-04
  • java map遍历的四种方法总结

    java map遍历的四种方法总结

    以下是我整理的关于java中map的遍历的四种方法。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • Spring中@ControllerAdvice注解的用法解析

    Spring中@ControllerAdvice注解的用法解析

    这篇文章主要介绍了Spring中@ControllerAdvice注解的用法解析,顾名思义,@ControllerAdvice就是@Controller 的增强版,@ControllerAdvice主要用来处理全局数据,一般搭配@ExceptionHandler、@ModelAttribute以及@InitBinder使用,需要的朋友可以参考下
    2023-10-10
  • 如何解决IDEA中JSP页面部分出现绿色背景色问题

    如何解决IDEA中JSP页面部分出现绿色背景色问题

    这篇文章主要介绍了如何解决IDEA中JSP页面部分出现绿色背景色问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12

最新评论