最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

構(gòu)建Java樹結(jié)構(gòu)的三種實現(xiàn)方法

 更新時間:2025年06月24日 08:53:36   作者:yololee_  
這篇文章主要介紹了構(gòu)建Java樹結(jié)構(gòu)的三種實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一、準備工作

表結(jié)構(gòu)

CREATE TABLE `asset_classification` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `className` varchar(50) NOT NULL COMMENT '分類名',
  `status` tinyint(2) NOT NULL COMMENT '狀態(tài)(0:使用中 1:停用)',
  `type` tinyint(2) NOT NULL COMMENT '類別(0:設(shè)備 1:物料 2:附件)',
  `writeable` tinyint(2) NOT NULL COMMENT '1:不可編輯 0:可編輯',
  `parentId` int(11) NOT NULL COMMENT '父類id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;

部分表數(shù)據(jù)

在這里插入圖片描述

二、三種方式

  • 原始遞歸
  • 利用Java 8 Stream流進行處理(原理還是遞歸)
  • Stream流升級構(gòu)建

controller層

@RestController
public class TestController {

    @Autowired
    private AssetClassificationBiz assetClassificationBiz;

    @GetMapping("/tree")
    public HttpResponseTemp<?> getTree(){

        List<AssetClassification> assetClassificationList = assetClassificationBiz.selectAll();

        List<TreeUtil.TreeSelect> list = new ArrayList<>();

        for (AssetClassification assetClassification : assetClassificationList) {
            TreeUtil.TreeSelect treeSelect = new TreeUtil.TreeSelect();
            treeSelect.setId(Convert.toLong(assetClassification.getId()));
            treeSelect.setLabel(assetClassification.getClassName());
            treeSelect.setParentId(Convert.toLong(assetClassification.getParentId()));
            list.add(treeSelect);
        }

        //原始遞歸
        List<TreeUtil.TreeSelect> list1 = TreeUtil.buildTree(list);
        //利用Java 8 Stream流進行處理(原理還是遞歸)
        List<TreeUtil.TreeSelect> list2 = TreeUtil.buildTreeByStream(list);
        //Stream流升級構(gòu)建
        List<TreeUtil.TreeSelect> list3 = TreeUtil.buildTreeByAllStream(list);

        return ResultStat.OK.wrap(list3);
    }
}

構(gòu)建樹結(jié)構(gòu)工具類(三種方式)

/**
 * @ClassName TreeUtil
 * @Description 構(gòu)建樹結(jié)構(gòu)工具類
 * @Author hl
 * @Date 2022/9/28 15:13
 * @Version 1.0
 */
public class TreeUtil {


    /**
     * Stream流升級構(gòu)建
     * @param trees
     * @return
     */
    public static List<TreeSelect> buildTreeByAllStream(List<TreeSelect> trees){
        return trees.stream().filter(m -> m.getParentId() == 0).peek(
                (m) -> m.setChildren(getChildrenList(m, trees))
        ).collect(Collectors.toList());

    }

    /**
     * 獲取子節(jié)點列表
     * @param tree
     * @param list
     * @return
     */
    public static List<TreeSelect> getChildrenList(TreeSelect tree, List<TreeSelect> list){
        return list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).peek(
                (item) -> item.setChildren(getChildrenList(item, list))
        ).collect(Collectors.toList());
    }



    /**
     * 利用Java 8 Stream流進行處理(原理還是遞歸)
     * @param trees
     * @return
     */
    public static List<TreeSelect> buildTreeByStream(List<TreeSelect> trees){
        //獲取parentId = 0的根節(jié)點
        List<TreeSelect> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
        //根據(jù)parentId進行分組
        Map<Long, List<TreeSelect>> map = trees.stream().collect(Collectors.groupingBy(TreeSelect::getParentId));
        recursionFnTree(list, map);
        return list;
    }

    /**
     * 遞歸遍歷節(jié)點
     * @param list
     * @param map
     */
    public static void recursionFnTree(List<TreeSelect> list, Map<Long, List<TreeSelect>> map){
        for (TreeSelect treeSelect : list) {
            List<TreeSelect> childList = map.get(treeSelect.getId());
            treeSelect.setChildren(childList);
            if (null != childList && 0 < childList.size()){
                recursionFnTree(childList,map);
            }
        }
    }


    /**
     * 構(gòu)建前端所需要樹結(jié)構(gòu)
     *
     * @param trees 列表
     * @return 樹結(jié)構(gòu)列表
     */
    public static List<TreeSelect> buildTree(List<TreeSelect> trees) {
        List<TreeSelect> returnList = new ArrayList<>();
        List<Long> tempList = new ArrayList<>();
        for (TreeSelect tree : trees) {
            tempList.add(tree.getId());
        }

        for (TreeSelect treeSelect : trees) {
            // 如果是頂級節(jié)點, 遍歷該父節(jié)點的所有子節(jié)點
            if (!tempList.contains(treeSelect.getParentId())) {
                recursionFn(trees, treeSelect);
                returnList.add(treeSelect);
            }
        }

        if (returnList.isEmpty()) {
            returnList = trees;
        }
        return returnList;
    }
    /**
     * 遞歸列表
     */
    private static void recursionFn(List<TreeSelect> list, TreeSelect t) {
        // 得到子節(jié)點列表
        List<TreeSelect> childList = getChildList(list, t);
        t.setChildren(childList);
        for (TreeSelect tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子節(jié)點列表
     */
    private static List<TreeSelect> getChildList(List<TreeSelect> list, TreeSelect t) {
        List<TreeSelect> tlist = new ArrayList<>();
        for (TreeSelect n : list) {
            if (ObjectUtil.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判斷是否有子節(jié)點
     */
    private static boolean hasChild(List<TreeSelect> list, TreeSelect t) {
        return getChildList(list, t).size() > 0;
    }



    static class TreeSelect implements Serializable {

        /** 節(jié)點ID */
        private Long id;

        /** 節(jié)點名稱 */
        private String label;

        /** 父ID */
        private Long parentId;

        /** 子節(jié)點 */
        private List<TreeSelect> children;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public List<TreeSelect> getChildren() {
            return children;
        }

        public void setChildren(List<TreeSelect> children) {
            this.children = children;
        }

        public Long getParentId() {
            return parentId;
        }

        public void setParentId(Long parentId) {
            this.parentId = parentId;
        }
    }
}

執(zhí)行結(jié)果

在這里插入圖片描述

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java利用endorsed如何覆蓋jdk提供的類詳解

    Java利用endorsed如何覆蓋jdk提供的類詳解

    這篇文章主要給大家介紹了關(guān)于Java利用endorsed如何覆蓋jdk提供的類的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧。
    2017-09-09
  • Lock、Condition實現(xiàn)簡單的生產(chǎn)者消費者模式示例

    Lock、Condition實現(xiàn)簡單的生產(chǎn)者消費者模式示例

    這篇文章主要介紹了Lock、Condition實現(xiàn)簡單的生產(chǎn)者消費者模式示例,需要的朋友可以參考下
    2014-04-04
  • Spring中的@AliasFor標簽的用法及說明

    Spring中的@AliasFor標簽的用法及說明

    Spring框架中的@AliasFor標簽用于定義注解屬性的別名,使得在同一個注解中可以使用相同的屬性值,從而提高代碼的可讀性和可維護性
    2026-03-03
  • java遠程調(diào)用接口、URL的方式代碼

    java遠程調(diào)用接口、URL的方式代碼

    我們都知道接口有自己本地的,也有遠程別人寫好的,而調(diào)用遠程接口的就需要使用遠程調(diào)用啦,這篇文章主要給大家介紹了關(guān)于java遠程調(diào)用接口、URL的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • Spring Boot中RabbitMQ自動配置的介紹、原理和使用方法

    Spring Boot中RabbitMQ自動配置的介紹、原理和使用方法

    本文介紹了Spring Boot中RabbitMQ自動配置的介紹、原理和使用方法,通過本文的介紹,我們希望讀者能夠更好地理解Spring Boot中RabbitMQ的使用方法,并在項目中更加靈活地應(yīng)用,感興趣的朋友跟隨小編一起看看吧
    2023-07-07
  • springboot項目用maven插件打包時報錯的解決方法

    springboot項目用maven插件打包時報錯的解決方法

    文章介紹了解決Spring Boot項目使用Maven插件打包時遇到JDK版本無效問題的步驟,本文分步驟給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Springcloud Config支持本地配置文件的方法示例

    Springcloud Config支持本地配置文件的方法示例

    這篇文章主要介紹了Springcloud Config支持本地配置文件的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2020-02-02
  • Java中Swagger生成后端接口測試的詳細教程

    Java中Swagger生成后端接口測試的詳細教程

    Swagger是一套圍繞OpenAPI規(guī)范構(gòu)建的開源工具集,用于設(shè)計、構(gòu)建、文檔化和消費RESTful Web服務(wù),供了一種標準化、語言無關(guān)的接口來描述REST API,本文給大家介紹了Java中Swagger生成后端接口測試的詳細教程,需要的朋友可以參考下
    2025-06-06
  • Java SpringBoot開發(fā)小技巧詳解

    Java SpringBoot開發(fā)小技巧詳解

    這篇文章主要介紹了淺談SpringBoot項目如何讓前端開發(fā)提高效率(小技巧),主要介紹了Swagger和Nginx提高效率的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot分段處理List集合多線程批量插入數(shù)據(jù)方式

    SpringBoot分段處理List集合多線程批量插入數(shù)據(jù)方式

    文章介紹如何處理大數(shù)據(jù)量List批量插入數(shù)據(jù)庫的優(yōu)化方案:通過拆分List并分配獨立線程處理,結(jié)合Spring線程池與異步方法提升效率,推薦使用batch模式而非foreach標簽,注意插入數(shù)據(jù)無序性
    2025-08-08

最新評論

孟津县| 隆化县| 黄陵县| 乌兰浩特市| 金秀| 扎兰屯市| 天气| 吉安市| 姜堰市| 安吉县| 合江县| 临猗县| 德州市| 房山区| 朝阳市| 清新县| 沅江市| 平陆县| 神农架林区| 白玉县| 庆阳市| 紫云| 呼和浩特市| 阿克陶县| 义乌市| 肇庆市| 兴业县| 沿河| 阳春市| 康定县| 儋州市| 襄垣县| 北川| 桓台县| 尤溪县| 镇沅| 通山县| 九台市| 姜堰市| 玉田县| 南漳县|