溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

深入淺析java中的TreeUtil菜單遞歸工具類(lèi)

發(fā)布時(shí)間:2020-11-07 15:27:11 來(lái)源:億速云 閱讀:530 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

深入淺析java中的TreeUtil菜單遞歸工具類(lèi)?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

菜單樹(shù)(詳細(xì))

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;
  }
}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI