欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、準(zhǔ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實現(xiàn)四連環(huán)棋游戲

    Java實現(xiàn)四連環(huán)棋游戲

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)四連環(huán)棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • java數(shù)據(jù)庫數(shù)據(jù)分批讀取的實現(xiàn)示例

    java數(shù)據(jù)庫數(shù)據(jù)分批讀取的實現(xiàn)示例

    在處理大量數(shù)據(jù)時,直接從數(shù)據(jù)庫一次性讀取所有數(shù)據(jù)可能會導(dǎo)致內(nèi)存溢出或者性能下降,本文就來介紹一下java數(shù)據(jù)庫數(shù)據(jù)分批讀取的實現(xiàn)示例,感興趣的可以了解一下
    2024-01-01
  • springmvc實現(xiàn)導(dǎo)出數(shù)據(jù)信息為excle表格示例代碼

    springmvc實現(xiàn)導(dǎo)出數(shù)據(jù)信息為excle表格示例代碼

    本篇文章主要介紹了springmvc實現(xiàn)導(dǎo)出數(shù)據(jù)信息為excle表格,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧。
    2017-01-01
  • SpringMVC整合SSM實現(xiàn)表現(xiàn)層數(shù)據(jù)封裝詳解

    SpringMVC整合SSM實現(xiàn)表現(xiàn)層數(shù)據(jù)封裝詳解

    這篇文章主要介紹了SpringMVC整合SSM實現(xiàn)表現(xiàn)層數(shù)據(jù)封裝,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • Java springboot探究配置文件優(yōu)先級

    Java springboot探究配置文件優(yōu)先級

    在springboot項目中,我們可以通過在yml文件中設(shè)置變量,再通過@Value注解來獲得這個變量并使用,但如果這個項目已經(jīng)部署到服務(wù)器上,我們想更改這個數(shù)據(jù)了需要怎么做呢,其實在springboot項目中,配置文件是有優(yōu)先級的
    2023-04-04
  • Java中的Timer和TimerTask詳細(xì)解讀

    Java中的Timer和TimerTask詳細(xì)解讀

    這篇文章主要介紹了Java中的Timer和TimerTask詳細(xì)解讀,??Timer和TimerTask可以做為實現(xiàn)線程的第三種方式,前兩中方式分別是繼承自Thread類和實現(xiàn)Runnable接口,需要的朋友可以參考下
    2023-10-10
  • MybatisPlus處理大表查詢的實現(xiàn)步驟

    MybatisPlus處理大表查詢的實現(xiàn)步驟

    在實際工作中當(dāng)指定查詢數(shù)據(jù)過大時,我們一般使用分頁查詢的方式一頁一頁的將數(shù)據(jù)放到內(nèi)存處理,本文主要介紹了MybatisPlus處理大表查詢的實現(xiàn)步驟,感興趣的可以了解一下
    2024-08-08
  • 解析Mybatis SqlSessionFactory初始化原理

    解析Mybatis SqlSessionFactory初始化原理

    本文主要介紹了Mybatis SqlSessionFactory初始化原理,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Java中Json與List、Map、entity的互相轉(zhuǎn)化

    Java中Json與List、Map、entity的互相轉(zhuǎn)化

    在開發(fā)中,Json轉(zhuǎn)換的場景往往也就是那么幾個,本文主要介紹了Java中Json與List、Map、entity的互相轉(zhuǎn)化,具有一定的參考價值,感興趣的可以了解一下
    2022-07-07
  • Java中的四種單例模式淺析

    Java中的四種單例模式淺析

    這篇文章主要給大家介紹了關(guān)于Java中四種單例模式的相關(guān)資料,其中包括餓漢式、懶漢式、懶漢式(雙重鎖)及內(nèi)部類等四種,分別給出了詳細(xì)的示例代碼和介紹,需要的朋友們下面來一起看看吧。
    2017-05-05

最新評論