Java構建菜單樹的實現(xiàn)示例
在后臺系統(tǒng)中,菜單欄有著嚴格的層次結構,它是系統(tǒng)方便與否的重要功能,像一級菜單,二級菜單,三級菜單甚至更多層級的菜單,我們將它稱為菜單樹,菜單樹往往需要后端程序員來構建好了之后再給前端程序員,前端程序員再去渲染到頁面上這樣一個流程,而且菜單列表是動態(tài)變化的。
那么該如何構建一個菜單樹呢?
在數(shù)據(jù)庫中,menu 表最常見的字段
id(主鍵)
parent_id(父級ID)
menu_name(菜單名稱)
path(路徑)
...(等等)
思路
- 我們可以把菜單列表返回,獲取parent_id字段等于0的節(jié)點,稱為根節(jié)點,這樣的節(jié)點代表一級菜單
- 再通過根節(jié)點的主鍵去尋找子菜單,因為要有多及菜單,所以要用遞歸構建子樹,直到沒有子菜單為止
- 最后通過構建完整的菜單樹
menu 實體類
public class Menu { ? ? ? private Long id; ? ? ? private Long parentId; ? ? ? private String name; ? ? ? private List<Menu> childrenList; ? ? ? public Menu(Long id, Long parentId, String name) { ? ? ? ? ? this.id = id; ? ? ? ? ? this.parentId = parentId; ? ? ? ? ? this.name = name; ? ? ? } ? ? ? // getter setter... }
構建菜單樹分為以下幾個步驟
返回菜單的根節(jié)點
private List<Menu> getRootNode() { ? ? ? List<Menu> rootNode = new ArrayList<>(); ? ? ? menuList.forEach(item -> { ? ? ? ? ? if (item.getParentId() == 0) { ? ? ? ? ? ? ? rootNode.add(item); ? ? ? ? ? } ? ? ? }); ? ? ? return rootNode; ? }
構建子菜單樹
private Menu builderChildrenNode(Menu rootNode) { ? ? ? List<Menu> childrenList = new ArrayList<>(); ? ? ? menuList.forEach(item -> { ? ? ? ? ? if (Objects.equals(item.getParentId(), rootNode.getId())) { ? ? ? ? ? // 還需要遍歷三級菜單以后的 ? ? ? ? ? Menu menu = builderChildrenNode(item); ? ? ? ? ? childrenList.add(menu); ? ? ? ? ? } ? ? ? }); ? ? ? rootNode.setChildrenList(childrenList); ? ? ? return rootNode; ? }
構建菜單樹
public List<Menu> buildTree() { ? ? ? List<Menu> menus = getRootNode(); ? ? ? menus.forEach(this::builderChildrenNode); ? ? ? return menus; ? }
完整代碼
public class MenuTree { ? ? ? private final List<Menu> menuList; ? ? ? public MenuTree(List<Menu> menuList) { ? ? ? ? ? this.menuList = menuList; ? ? ? } ? ? ? /** ? ? ? * 獲取根結點 ? ? ? * ? ? ? * @return ? ? ? */ ? ? ? private List<Menu> getRootNode() { ? ? ? ? ? List<Menu> rootNode = new ArrayList<>(); ? ? ? ? ? menuList.forEach(item -> { ? ? ? ? ? ? ? if (item.getParentId() == 0) { ? ? ? ? ? ? ? ? ? rootNode.add(item); ? ? ? ? ? ? ? } ? ? ? ? ? }); ? ? ? ? ? return rootNode; ? ? ? } ? ? ? /** ? ? ? * 構建子樹 ? ? ? * ? ? ? * @param rootNode ? ? ? * @return ? ? ? */ ? ? ? private Menu builderChildrenNode(Menu rootNode) { ? ? ? ? ? List<Menu> childrenList = new ArrayList<>(); ? ? ? ? ? menuList.forEach(item -> { ? ? ? ? ? ? ? if (Objects.equals(item.getParentId(), rootNode.getId())) { ? ? ? ? ? ? ? // 還需要遍歷三級菜單以后的 ? ? ? ? ? ? ? Menu menu = builderChildrenNode(item); ? ? ? ? ? ? ? childrenList.add(menu); ? ? ? ? ? ? ? } ? ? ? ? ? }); ? ? ? ? ? rootNode.setChildrenList(childrenList); ? ? ? ? ? return rootNode; ? ? ? } ? ? ? /** ? ? ? * 構建樹 ? ? ? * ? ? ? * @return ? ? ? */ ? ? ? public List<Menu> buildTree() { ? ? ? ? ? List<Menu> menus = getRootNode(); ? ? ? ? ? menus.forEach(this::builderChildrenNode); ? ? ? ? ? return menus; ? ? ? } ? }
測試
用到了fastjson2依賴
<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.28</version> </dependency>
public class MenuTreeTest { ? ? ? public static void main(String[] args) { ? ? ? ? ? List<Menu> menuList = new ArrayList<>(); ? ? ? ? ? menuList.add(new Menu(1L, 0L, "一級菜單1")); ? ? ? ? ? menuList.add(new Menu(2L, 0L, "一級菜單2")); ? ? ? ? ? menuList.add(new Menu(3L, 0L, "一級菜單3")); ? ? ? ? ? menuList.add(new Menu(4L, 1L, "二級菜單1")); ? ? ? ? ? menuList.add(new Menu(5L, 1L, "二級菜單2")); ? ? ? ? ? menuList.add(new Menu(6L, 4L, "三級菜單")); ? ? ? ? ? menuList.add(new Menu(7L, 6L, "四級菜單")); ? ? ? ? ? MenuTree menuTree = new MenuTree(menuList); ? ? ? ? ? List<Menu> menus = menuTree.buildTree(); ? ? ? ? ? String jsonString = JSON.toJSONString(menus); ? ? ? ? ? System.out.println(jsonString); ? ? ? } ? }
結果
[{ "childrenList": [{ "childrenList": [{ "childrenList": [{ "childrenList": [], "id": 7, "name": "四級菜單", "parentId": 6 }], "id": 6, "name": "三級菜單", "parentId": 4 }], "id": 4, "name": "二級菜單1", "parentId": 1 }, { "childrenList": [], "id": 5, "name": "二級菜單2", "parentId": 1 }], "id": 1, "name": "一級菜單1", "parentId": 0 }, { "childrenList": [], "id": 2, "name": "一級菜單2", "parentId": 0 }, { "childrenList": [], "id": 3, "name": "一級菜單3", "parentId": 0 }]
到此這篇關于Java構建菜單樹的實現(xiàn)示例的文章就介紹到這了,更多相關Java構建菜單樹內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Springboot實現(xiàn)自定義錯誤頁面的方法(錯誤處理機制)
這篇文章主要介紹了Springboot實現(xiàn)自定義錯誤頁面的方法(錯誤處理機制),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01springboot項目攔截器重定向循環(huán)問題的解決
這篇文章主要介紹了springboot項目攔截器重定向循環(huán)問題的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09Java Spring @Autowired的這些騷操作,你都知道嗎
這篇文章主要介紹了徹底搞明白Spring中的自動裝配和Autowired注解的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-09-09spring cloud實現(xiàn)Eureka注冊中心的HA的方法
本篇文章主要介紹了spring cloud實現(xiàn)Eureka注冊中心的HA的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01SpringBoot3集成SLF4J+logback進行日志記錄的實現(xiàn)
本文主要介紹了SpringBoot3集成SLF4J+logback進行日志記錄的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01