1. 程式人生 > 實用技巧 >Java遞迴的方式構造一棵樹

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 }