经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
java后端操作树结构 - spiderMan1-1
来源:cnblogs  作者:spiderMan1-1  时间:2023/10/25 10:13:42  对本文有异议

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

(1)递归
普通递归方法

  1. public Result getBmsMenuList(UserSessionVO userSessionInfo) {
  2. // 查询顶级节点菜单
  3. List<BmsMenuVO> bmsMenuVOList = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO());
  4. for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
  5. getBmsMenuListByRecursion(bmsMenuVO);
  6. }
  7. return Result.createWithModels(null, bmsMenuVOList);
  8. }
  9. private void getBmsMenuListByRecursion(BmsMenuVO bmsMenuVO) {
  10. List<BmsMenuVO> bmsMenuVOS = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO().setParentId(bmsMenuVO.getId()));
  11. if (CollectionUtils.isEmpty(bmsMenuVOS)) {
  12. return;
  13. }
  14. bmsMenuVO.setChildBmsMenuList(bmsMenuVOS);
  15. for (BmsMenuVO menuVO : bmsMenuVOS) {
  16. getBmsMenuListByRecursion(menuVO);
  17. }
  18. }

stream流递归方法

  1. //获取父节点
  2. List<TreeSelect> collect = trees.stream().filter(m -> m.getParentId() == 0).map(
  3. (m) -> {
  4. m.setChildren(getChildrenList(m, trees));
  5. return m;
  6. }
  7. ).collect(Collectors.toList());
  8. /**
  9. * 获取子节点列表
  10. * @param tree
  11. * @param list
  12. * @return
  13. */
  14. public static List<TreeSelect> getChildrenList(TreeSelect tree, List<TreeSelect> list){
  15. List<TreeSelect> children = list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).map(
  16. (item) -> {
  17. item.setChildren(getChildrenList(item, list));
  18. return item;
  19. }
  20. ).collect(Collectors.toList());
  21. return children;
  22. }

(2)双层for循环

  1. // 查询主节点
  2. List<BmsMenuVO> bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
  3. // 拼装结果
  4. List<BmsMenuVO> bmsMenuTree = new ArrayList<>();
  5. for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
  6. // 根节点的父Id为null
  7. if (bmsMenuVO.getParentId() == null) {
  8. bmsMenuTree.add(bmsMenuVO);
  9. }
  10. for (BmsMenuVO menuVO : bmsMenuVOList) {
  11. if (menuVO.getParentId() != null && menuVO.getParentId().equals(bmsMenuVO.getId())) {
  12. if (CollectionUtils.isEmpty(bmsMenuVO.getChildBmsMenuList())) {
  13. bmsMenuVO.setChildBmsMenuList(new ArrayList<>());
  14. }
  15. bmsMenuVO.getChildBmsMenuList().add(menuVO);
  16. }
  17. }
  18. }
  19. // 返回结果
  20. return Result.createWithModels(null, bmsMenuTree);

(3)map遍历

  1. // 查询所有节点
  2. List<BmsMenuVO> bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
  3. // 拼装结果
  4. List<BmsMenuVO> bmsMenuTree = new ArrayList<>();
  5. // 用来存储节点的子元素map
  6. Map<Long, BmsMenuVO> childBmsMenuMap = new LinkedHashMap<>();
  7. for (BmsMenuVO menuVO : bmsMenuVOList) {
  8. childBmsMenuMap.put(menuVO.getId(), menuVO);
  9. }
  10. for (Long bmsMenuId : childBmsMenuMap.keySet()) {
  11. BmsMenuVO menuVO = childBmsMenuMap.get(bmsMenuId);
  12. Long parentId = menuVO.getParentId();
  13. if (parentId == null) {
  14. bmsMenuTree.add(menuVO);
  15. } else {
  16. BmsMenuVO parentMenuVO = childBmsMenuMap.get(parentId);
  17. if (parentMenuVO.getChildBmsMenuList() == null) {
  18. parentMenuVO.setChildBmsMenuList(new ArrayList<>());
  19. }
  20. parentMenuVO.getChildBmsMenuList().add(menuVO);
  21. }
  22. }

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

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

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

  1. @Data
  2. public class TreeDto {
  3. private String id;
  4. private String name;
  5. private List<TreeDto> subsetTreeDtoList;
  6. public TreeDto(String id,String name,List<TreeDto> subsetTreeDtoList){
  7. this.id = id;
  8. this.name = name;
  9. this.subsetTreeDtoList = subsetTreeDtoList;
  10. }
  11. }

筛选

  1. /**
  2. * 树形筛选查找
  3. * @param treeDtoList 树形集合
  4. * @param idList 筛选条件(可以是其他条件)
  5. * @return 包含的节点数据
  6. */
  7. public static List<TreeDto> screenTree(List<TreeDto> treeDtoList, List<String> idList){
  8. //最后返回的筛选完成的集合
  9. List<TreeDto> screeningOfCompleteList = new ArrayList<>();
  10. if (listIsNotEmpty(treeDtoList) && listIsNotEmpty(idList)){
  11. for (TreeDto treeDto : treeDtoList){
  12. List<TreeDto> subsetList = treeDto.getSubsetTreeDtoList();
  13. //递归筛选完成后的返回的需要添加的数据
  14. TreeDto addTreeDto = getSubsetPmsPlanPo(treeDto,subsetList,idList);
  15. if (isNotEmpty(addTreeDto)){
  16. screeningOfCompleteList.add(addTreeDto);
  17. }
  18. }
  19. return screeningOfCompleteList;
  20. }
  21. return null;
  22. }
  23. /**
  24. * 筛选符合的集合并返回
  25. * @param treeDto 树形类
  26. * @param subsetTreeDtoList 子集集合
  27. * @param idList 筛选条件
  28. * @return 筛选成功的类
  29. */
  30. public static TreeDto getSubsetPmsPlanPo(TreeDto treeDto,List<TreeDto> subsetTreeDtoList,List<String> idList){
  31. //作为筛选条件的判断值
  32. String id = treeDto.getId();
  33. //有子集时继续向下寻找
  34. if (listIsNotEmpty(subsetTreeDtoList)){
  35. List<TreeDto> addTreeDtoList = new ArrayList<>();
  36. for (TreeDto subsetTreeDto : subsetTreeDtoList){
  37. List<TreeDto> subsetList = subsetTreeDto.getSubsetTreeDtoList();
  38. TreeDto newTreeDto = getSubsetPmsPlanPo(subsetTreeDto,subsetList,idList);
  39. //当子集筛选完不为空时添加
  40. if (isNotEmpty(newTreeDto)){
  41. addTreeDtoList.add(newTreeDto);
  42. }
  43. }
  44. //子集满足条件筛选时集合不为空时,替换对象集合内容并返回当前对象
  45. if (listIsNotEmpty(addTreeDtoList)){
  46. treeDto.setSubsetTreeDtoList(addTreeDtoList);
  47. return treeDto;
  48. //当前对象子集对象不满足条件时,判断当前对象自己是否满足筛选条件,满足设置子集集合为空,并返回当前对象
  49. }else if (listIsEmpty(addTreeDtoList) && idList.contains(id)){
  50. treeDto.setSubsetTreeDtoList(null);
  51. return treeDto;
  52. }else {
  53. //未满足筛选条件直接返回null
  54. return null;
  55. }
  56. }else {
  57. //无子集时判断当前对象是否满足筛选条件
  58. if (idList.contains(id)){
  59. return treeDto;
  60. }else {
  61. return null;
  62. }
  63. }
  64. }
  65. /**
  66. * 判断集合为空
  67. * @param list 需要判断的集合
  68. * @return 集合为空时返回 true
  69. */
  70. public static boolean listIsEmpty(Collection list){
  71. return (null == list || list.size() == 0);
  72. }
  73. /**
  74. * 判断集合非空
  75. * @param list 需要判断的集合
  76. * @return 集合非空时返回 true
  77. */
  78. public static boolean listIsNotEmpty(Collection list){
  79. return !listIsEmpty(list);
  80. }
  81. /**
  82. * 判断对象为null或空时
  83. * @param object 对象
  84. * @return 对象为空或null时返回 true
  85. */
  86. public static boolean isEmpty(Object object) {
  87. if (object == null) {
  88. return (true);
  89. }
  90. if ("".equals(object)) {
  91. return (true);
  92. }
  93. if ("null".equals(object)) {
  94. return (true);
  95. }
  96. return (false);
  97. }
  98. /**
  99. * 判断对象非空
  100. * @param object 对象
  101. * @return 对象为非空时返回 true
  102. */
  103. public static boolean isNotEmpty(Object object) {
  104. if (object != null && !object.equals("") && !object.equals("null")) {
  105. return (true);
  106. }
  107. return (false);
  108. }
  109. public static void main(String[] args) {
  110. TreeDto treeDto1 = new TreeDto("1","A",new ArrayList<TreeDto>());
  111. TreeDto treeDto1_1 = new TreeDto("1.1","A-A",new ArrayList<TreeDto>());
  112. TreeDto treeDto1_2 = new TreeDto("1.2","A-B",new ArrayList<TreeDto>());
  113. TreeDto treeDto1_3 = new TreeDto("1.3","A-C",new ArrayList<TreeDto>());
  114. treeDto1.getSubsetTreeDtoList().add(treeDto1_1);
  115. treeDto1.getSubsetTreeDtoList().add(treeDto1_2);
  116. treeDto1.getSubsetTreeDtoList().add(treeDto1_3);
  117. TreeDto treeDto2 = new TreeDto("2","B",new ArrayList<TreeDto>());
  118. TreeDto treeDto2_1 = new TreeDto("2.1","B-A",new ArrayList<TreeDto>());
  119. TreeDto treeDto2_2 = new TreeDto("2.2","B-B",new ArrayList<TreeDto>());
  120. TreeDto treeDto2_3 = new TreeDto("2.3","B-C",new ArrayList<TreeDto>());
  121. TreeDto treeDto2_3_1 = new TreeDto("2.3.1","B-C-A",null);
  122. treeDto2.getSubsetTreeDtoList().add(treeDto2_1);
  123. treeDto2.getSubsetTreeDtoList().add(treeDto2_2);
  124. treeDto2.getSubsetTreeDtoList().add(treeDto2_3);
  125. treeDto2.getSubsetTreeDtoList().get(2).getSubsetTreeDtoList().add(treeDto2_3_1);
  126. String[] array = {"1.3","2.2","2.3.1"};
  127. List<String> idList = Arrays.asList(array);
  128. List<TreeDto> treeDtoList = new ArrayList<>();
  129. treeDtoList.add(treeDto1);
  130. treeDtoList.add(treeDto2);
  131. System.out.println(JSON.toJSONString(screenTree(treeDtoList,idList)));
  132. }
  133. }

返回结果为
image

原文链接:https://www.cnblogs.com/cgy1995/p/17782289.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号