java TreeUtil菜單遞歸工具類
本文實(shí)例為大家分享了java TreeUtil菜單遞歸工具類的具體代碼,供大家參考,具體內(nèi)容如下
package com.admin.manager.storeService.util; import com.admin.manager.storeService.entity.Menu; import java.util.ArrayList; import java.util.List; /** * @author m * @date 2019/12/16 */ public class TreeUtil { /** * 獲取菜單樹(shù) * @param menus 所有菜單 * @return */ public static List<Menu> menuTree(List<Menu> menus) { //返回的菜單樹(shù) List<Menu> rootMenus = new ArrayList<>(); for (Menu menu : menus) { //pid(上級(jí)Id)為0的是根菜單 if ("0".equals(menu.getPid())) { rootMenus.add(menu); } } //遍歷,找到二級(jí)菜單(根菜單的id和所有菜單中的pid比較) for (Menu rootMenu : rootMenus) { List<Menu> child = getChild(String.valueOf(rootMenu.getId()), menus); rootMenu.setChildren(child); } return rootMenus; } /** * 遞歸獲取下級(jí)菜單 * @param pid 上級(jí)Id * @param menus 所有菜單 * @return */ public static List<Menu> getChild(String pid, List<Menu> menus) { //子菜單列表 List<Menu> childList = new ArrayList<>(); for (Menu menu : menus) { if (pid.equals(menu.getPid())) { childList.add(menu); } } //遍歷 遞歸獲取子菜單的子菜單 for (Menu menu : childList) { List<Menu> child = getChild(String.valueOf(menu.getId()), menus); menu.setChildren(child); } //遞歸出口 childList長(zhǎng)度為0 if (childList.size() == 0) { return new ArrayList<>(); } return childList; } }
上面這種遞歸,如果遇到大數(shù)據(jù)量,效率是極低的。比如前段時(shí)間剛實(shí)現(xiàn)了省市區(qū)鎮(zhèn)四層的樹(shù)結(jié)構(gòu),面對(duì)5萬(wàn)條的數(shù)據(jù),竟然120s才遞歸完,這也太慢了,將來(lái)需求變成了省市區(qū)鎮(zhèn)鄉(xiāng)五層的結(jié)構(gòu),那不就掛了?
大眼一看,不是跟上面的一樣嘛。仔細(xì)看 it.remove();
假設(shè)有五萬(wàn)的數(shù)據(jù),根節(jié)點(diǎn)1萬(wàn),二級(jí)節(jié)點(diǎn)1萬(wàn),三級(jí)節(jié)點(diǎn)1萬(wàn),4級(jí)節(jié)點(diǎn)2萬(wàn)。如果按照上面的邏輯走,每次都要從5萬(wàn)中數(shù)據(jù)遞歸查找;而下面的邏輯是找到N級(jí)節(jié)點(diǎn)并且在總list中刪除。假設(shè)找到根節(jié)點(diǎn)的1萬(wàn)數(shù)據(jù),并且把他們從總list中刪除,總list剩4萬(wàn)條數(shù)據(jù),依次這樣,到了找4級(jí)節(jié)點(diǎn)時(shí),總list就已經(jīng)剩2萬(wàn)條數(shù)據(jù)了,總數(shù)據(jù)量從5萬(wàn)變成了2萬(wàn),循環(huán)次數(shù)就少了,效率也就高了
import com.energy.service.vo.RegionTree; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @author m * @date 2020/4/2 */ public class TreeUtil { /** * 創(chuàng)建樹(shù)結(jié)構(gòu) * @param regionTrees * @return */ private List<RegionTree> tree(List<RegionTree> regionTrees) { //返回的節(jié)點(diǎn)樹(shù) List<RegionTree> rootNodes = new ArrayList<>(); Iterator<RegionTree> it = regionTrees.iterator(); while (it.hasNext()) { RegionTree next = it.next(); //parent(上級(jí)Id)為0的是根節(jié)點(diǎn) if ("0".equals(next.getParentId())) { rootNodes.add(next); it.remove(); } } //遍歷,找到二級(jí)節(jié)點(diǎn) for (RegionTree regionTree : rootNodes) { List<RegionTree> child = getChild(regionTrees, regionTree.getId().toString()); regionTree.setChildren(child); } return rootNodes; } /** * 查子節(jié)點(diǎn) * * @param regions * @param parentId * @return */ private List<RegionTree> getChild(List<RegionTree> regions, String parentId) { //子節(jié)點(diǎn)列表 List<RegionTree> childList = new ArrayList<>(); Iterator<RegionTree> it = regions.iterator(); while (it.hasNext()) { RegionTree regionTree = it.next(); if (parentId.equals(regionTree.getParentId())) { childList.add(regionTree); it.remove(); } } //遍歷 遞歸獲取子節(jié)點(diǎn)的子節(jié)點(diǎn) for (RegionTree regionTree : childList) { List<RegionTree> child = getChild(regions, regionTree.getId().toString()); regionTree.setChildren(child); } //遞歸出口 childList長(zhǎng)度為0 if (childList.size() == 0) { return new ArrayList<>(); } return childList; } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring boot進(jìn)行參數(shù)校驗(yàn)的方法實(shí)例詳解
這篇文章主要介紹了Spring boot進(jìn)行參數(shù)校驗(yàn)的方法實(shí)例詳解,非 常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-05-05Visual?Studio?Code配置Tomcat運(yùn)行Java?Web項(xiàng)目詳細(xì)步驟
VS Code是一款非常棒的文本編輯器,具有配置簡(jiǎn)單、功能豐富、輕量簡(jiǎn)潔的特點(diǎn),并且極其適合處理中小規(guī)模的代碼,這篇文章主要給大家介紹了關(guān)于Visual?Studio?Code配置Tomcat運(yùn)行Java?Web項(xiàng)目的詳細(xì)步驟,需要的朋友可以參考下2023-11-11java基于JDBC連接Oracle 11g Release2實(shí)例分析
這篇文章主要介紹了java基于JDBC連接Oracle 11g Release2的方法,實(shí)例分析了JDBC連接Oracle 11g Release2容易出現(xiàn)的異常與解決方法,需要的朋友可以參考下2015-06-06

Spring Cloud Gateway 記錄請(qǐng)求應(yīng)答數(shù)據(jù)日志操作

Java生成隨機(jī)數(shù)之Random與ThreadLocalRandom性能比較詳解

Java中String.split()的最詳細(xì)源碼解讀及注意事項(xiàng)

java中如何對(duì)arrayList按數(shù)字大小逆序排序