Java遞歸的方式構造一棵樹


  在實際代碼開發中,構造一棵樹是一個比較常見的業務場景,實現方式有多種多樣,但是如何以一種較為優雅的方式構造一棵樹,卻是一個值得深思的問題。

  下面的方法,整體思路是:

  1)首先查出所有的節點,這樣與數據庫只交互一次,減少IO;

  2)第二次采用遞歸的方式構建樹;

  3)采用 stream表達式,注意排序的兩種實現方式; 代碼如下:

 1   public List<CategoryEntity> queryTree() {  2 
 3         //1. 首先獲取所有的實體類
 4         List<CategoryEntity> categoryEntities = baseMapper.selectList(null);  5 
 6         //2. 組裝樹形結構  7         // 特點:  8         // 1) 首先查出所有的節點,與數據庫只交互一次,減少IO  9         // 2) 然后對查詢的節點采用遞歸的方式進行構造樹
10         List<CategoryEntity> firstMenu = categoryEntities.stream().filter((categoryEntity) -> { 11             return categoryEntity.getParentCid() == 0; 12         }).map((menu) -> { 13  menu.setChildren(getAllChildrenTree(menu, categoryEntities)); 14             return menu; 15             // 采用這種方式排序,注意非空判斷
16         }).sorted((menu1, menu2) -> { 17             return (menu1.getSort() == null ? 0 : menu1.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort()); 18  }).collect(Collectors.toList()); 19 
20 
21         return categoryEntities; 22    } 23 
24 
25     //遞歸獲取所有的子節點
26     private List<CategoryEntity> getAllChildrenTree(CategoryEntity root, List<CategoryEntity> all) { 27         List<CategoryEntity> tree = all.stream().filter((categoryEntity) -> { 28             return categoryEntity.getParentCid() == root.getCatId(); 29         }).map((categoryEntity) -> { 30             // 遞歸獲取 所有的子菜單
31  categoryEntity.setChildren(getAllChildrenTree(categoryEntity, all)); 32             return categoryEntity; 33             //一級菜單正序排列,其他的逆序排列 34             //采用兩種排序方式進行實現,采用這種方式排序,注意非空判斷 Comparator.nullsFirst(Integer::compareTo)
35  }).sorted(Comparator.comparing(CategoryEntity::getSort, Comparator.nullsFirst(Integer::compareTo)).reversed()) 36  .collect(Collectors.toList()); 37         return tree; 38     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM