首页 > 编程语言 >java后端操作树结构

java后端操作树结构

时间:2023-10-23 14:26:24浏览次数:41  
标签:return 后端 TreeDto 树结构 List add new java null

一、树结构的三种组装方式(递归.双层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)));
   }
}

返回结果为
image

标签:return,后端,TreeDto,树结构,List,add,new,java,null
From: https://www.cnblogs.com/cgy1995/p/17782289.html

相关文章

  • java上传文件到指定服务器
    Java上传文件到指定主机必须条件先决条件是要知道上传到指定的主机,需要知道它的用户密码。代码pom.xml<!--图片上传到服务器需要的依赖--><dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.54<......
  • Java学习之路(二)
    Java学习之路(二)1、流程控制语句1.1、顺序结构顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。执行流程:1.2、分支结构1.2.1、if语句格式一:单分支if(关系表达式){语句体; }执行流程:①......
  • Arthas(阿尔萨斯)Java 诊断工具
    Arthas(阿尔萨斯)能为你做什么?Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:1.这个类从哪个jar包加载的?为什么会报各种类相关的Exception?2.我改的代码为什么没有执行到?难道是我没commit?分支搞错了?3.遇到问题无......
  • 一台云服务器一个域名下,如何运行多个JAVA后端项目和多个VUE前端项目
    拿若依前后端分离版项目举例:修改前端代码ruoyi-ui/vue.config.js//二级目录名称ruoyi-uipublicPath:'/ruoyi-ui/',ruoyi-ui/src/router/index.jsexportdefaultnewRouter({mode:'history',//去掉url中的#base:'/ruoyi-ui/',//二级目录路径scrollBehavior:......
  • JavaSE day02【关键字,代码块,接口,枚举】测评
    选择题题目1(单选):下列关于static关键字描述错误的是()选项:​ A.静态成员被所类的所有对象共享​ B.可以通过对象调用,也可以通过类名调用,建议使用类名​ C.每调用一次都会在内存产生一个新的对象​ D.随着类的加载而加载,优先于对象存在题目2(多选):......
  • JavaSE day02-关键字,接口,代码块,枚举
    JavaSEday02-关键字,接口,代码块,枚举1关键字2代码块3接口4枚举1Java中的关键字1.1static关键字static关键字:静态的意思,可以修饰变量,也可以修饰方法,被static修饰的成员,我们叫做静态成员static特点:静态成员被所类的所有对象共享随着类的......
  • Java 入门 01~08 & Java 基础 01~04
    Java入门01~081.java的Helloword​ 创建helloWord.java文件->Javac编译完成后->java运行在终端{publicstaticvoidmain(String[]args){System.out.println("HelloWorld!");}}2.语言分类​ 编译型:完整编译以后可直接执行的。......
  • 小景的工具使用--Java诊断工具Arthas的使用说明
    小景最近在做程序和数据库的压测工作,期间监控压测数据,分析程序原因变成了一个待解决的问题,根据公司小伙伴的建议,接触了阿尔萨斯这个诊断工具,下面小景分别基于Linux操作系统和Windows操作系统,来详细的说下使用说明和使用心得。 Arthas(阿尔萨斯)是一个用于诊断Java应用程序的开源......
  • 以下是中国最丰富的10个Java资源网站及网址:
    以下是中国最丰富的10个Java资源网站及网址:CSDN-https://www.csdn.net/Java中国-http://www.javachina.net/开源中国-https://www.oschina.net/博客园-https://www.cnblogs.com/码云-https://gitee.com/极客学院-https://www.jikexueyuan.com/ITeye-http://w......
  • Java XXE漏洞原理研究
    一、JavaXML解析库简介Java解析XML的四种方式1、DOM(DocumentObjectModel)解析1)优缺点优点允许应用程序对数据和结构做出更改访问是双向的,可以在任何时候再树中上、下导航获取、操作任意部分的数据缺点解析XML文档的需要加载整个文档来构造层次结构,消耗内存资源......