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

詳解如何使用Java流API構(gòu)建樹形結(jié)構(gòu)數(shù)據(jù)

 更新時間:2024年04月02日 16:20:33   作者:大陽光男孩  
在實際開發(fā)中,構(gòu)建樹狀層次結(jié)構(gòu)是常見需求,本文主要為大家詳細(xì)介紹了如何使用Java 8 Stream API將扁平化的菜單數(shù)據(jù)轉(zhuǎn)換為具有層級關(guān)系的樹形結(jié)構(gòu),需要的可以參考下

簡介

在實際開發(fā)中,構(gòu)建樹狀層次結(jié)構(gòu)是常見需求,如組織架構(gòu)、目錄結(jié)構(gòu)或菜單系統(tǒng)。本教案通過解析給定的Java代碼,展示如何使用Java 8 Stream API將扁平化的菜單數(shù)據(jù)轉(zhuǎn)換為具有層級關(guān)系的樹形結(jié)構(gòu)。

1. 核心類定義 - Menu

@Data
@NoArgsConstructor
@AllArgsConstructor
static class Menu {
    private Long id;
    private String name;
    private Long parentId;
    private List<Menu> children;
}

提示:此處定義了一個名為Menu的類,它包含了菜單項的基本屬性,包括ID、名稱、父菜單ID以及一個用于存儲子菜單項的列表。

2. main方法解析及實現(xiàn)功能

輸入?yún)?shù):

List<Menu> menus:包含所有菜單項的集合。

輸出結(jié)果:

List<Menu>:一個僅包含頂級菜單項的列表,每個頂級菜單項已填充了其下級子菜單。

public static void main(String[] args) {
        List<Menu> menus = menusData();
        /**
         * 從菜單列表中篩選出頂級菜單,并為其添加子菜單。
         *
         * @param menus 菜單列表,包含所有菜單項。
         * @return 包含所有頂級菜單的列表,其中每個頂級菜單均已包含其所有子菜單。
         */
        List<Menu> topLevelMenus = menus.stream() // 使用流處理menus集合
                        .filter(menu -> menu.getParentId() == 0 || menus.stream().noneMatch(other -> other.getId().equals(menu.getParentId()))) // 篩選條件:父菜單ID為0或不存在對應(yīng)父菜單的菜單項
                        .peek(menu -> menu.setChildren(getChildren(menu, menus))) // 為每個頂級菜單設(shè)置子菜單
                        .collect(Collectors.toList()); // 將篩選后的頂級菜單集合轉(zhuǎn)換為List(Menu)類型
    }

3. 輔助方法——獲取指定菜單的所有子菜單

 /**
     * 獲取指定菜單的所有子菜單。
     *
     * @param menu 指定的菜單對象,我們要查找它的子菜單。
     * @param menus 所有菜單的列表,從中篩選出子菜單。
     * @return 返回一個包含指定菜單所有子菜單的列表。這個列表中的每個菜單對象都可能包含它們自己的子菜單列表。
     */
    private static List<Menu> getChildren(Menu menu, List<Menu> menus) {
        // 使用流對菜單列表進(jìn)行處理,篩選出指定菜單的子菜單
        return menus.stream()
                .filter(child -> child.getParentId().equals(menu.getId())) // 篩選條件:菜單的父菜單ID與指定菜單ID匹配
                .peek(child -> child.setChildren(getChildren(child, menus))) // 遞歸設(shè)置每個子菜單的子菜單列表
                .collect(Collectors.toList()); // 收集結(jié)果,生成列表
    }

4. 示例數(shù)據(jù)生成方法 —— menusData()

private static List<Menu> menusData() {
    return Arrays.asList(
            new Menu(1L, "一級菜單1", 0L, null),
            new Menu(2L, "二級菜單1", 1L, null),
            new Menu(3L, "三級菜單1", 2L, null),
            new Menu(4L, "一級菜單2", 0L, null),
            new Menu(5L, "二級菜單2", 4L, null),
            new Menu(6L, "一級菜單3", 0L, null)
    );
}

5.完整代碼,以及演示(TreeExample.java)

package com.tenement.auto;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class TreeExample {
 
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static
    class Menu {
        private Long id;
        private String name;
        private Long parentId;
 
        private List<Menu> children;
    }
 
    public static void main(String[] args) {
        List<Menu> menus = menusData();
        /**
         * 從菜單列表中篩選出頂級菜單,并為其添加子菜單。
         *
         * @param menus 菜單列表,包含所有菜單項。
         * @return 包含所有頂級菜單的列表,其中每個頂級菜單均已包含其所有子菜單。
         */
        List<Menu> topLevelMenus = menus.stream() // 使用流處理menus集合
                        .filter(menu -> menu.getParentId() == 0 || menus.stream().noneMatch(other -> other.getId().equals(menu.getParentId()))) // 篩選條件:父菜單ID為0或不存在對應(yīng)父菜單的菜單項
                        .peek(menu -> menu.setChildren(getChildren(menu, menus))) // 為每個頂級菜單設(shè)置子菜單
                        .collect(Collectors.toList()); // 將篩選后的頂級菜單集合轉(zhuǎn)換為List(Menu)類型
    }
 
    /**
     * 獲取指定菜單的所有子菜單。
     *
     * @param menu 指定的菜單對象,我們要查找它的子菜單。
     * @param menus 所有菜單的列表,從中篩選出子菜單。
     * @return 返回一個包含指定菜單所有子菜單的列表。這個列表中的每個菜單對象都可能包含它們自己的子菜單列表。
     */
    private static List<Menu> getChildren(Menu menu, List<Menu> menus) {
        // 使用流對菜單列表進(jìn)行處理,篩選出指定菜單的子菜單
        return menus.stream()
                .filter(child -> child.getParentId().equals(menu.getId())) // 篩選條件:菜單的父菜單ID與指定菜單ID匹配
                .peek(child -> child.setChildren(getChildren(child, menus))) // 遞歸設(shè)置每個子菜單的子菜單列表
                .collect(Collectors.toList()); // 收集結(jié)果,生成列表
    }
 
    private static List<Menu> menusData() {
        return Arrays.asList(
                new Menu(1L, "一級菜單1", 0L,null),
                new Menu(2L, "二級菜單1", 1L,null),
                new Menu(3L, "三級菜單1", 2L,null),
                new Menu(4L, "一級菜單2", 0L,null),
                new Menu(5L, "二級菜單2", 4L,null),
                new Menu(6L, "一級菜單3", 0L,null)
        );
    }
 
}

總結(jié)

該案例展示了如何利用Java 的Stream API對菜單數(shù)據(jù)進(jìn)行處理,首先篩選出頂級菜單項,并通過遞歸方式為其添加子菜單。最后,得到了一個完整的樹形菜單結(jié)構(gòu)。 

到此這篇關(guān)于詳解如何使用Java流API構(gòu)建樹形結(jié)構(gòu)數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Java流構(gòu)建樹形結(jié)構(gòu)數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中后臺線程實例解析

    Java中后臺線程實例解析

    這篇文章主要介紹了Java中后臺線程實例解析,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • MyBatis-Plus中的LambdaQuery用法實例詳解

    MyBatis-Plus中的LambdaQuery用法實例詳解

    LambdaQueryWrapper是MyBatis-Plus的類型安全查詢工具,通過Lambda表達(dá)式簡化條件構(gòu)建,避免硬編碼字段名,提升代碼可讀性、維護(hù)性及重構(gòu)友好性,適用于單表查詢場景,本文給大家介紹MyBatis-Plus中的LambdaQuery用法,感興趣的朋友一起看看吧
    2025-07-07
  • Java設(shè)計模式之橋接模式

    Java設(shè)計模式之橋接模式

    這篇文章介紹了Java設(shè)計模式之橋接模式,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • Java并發(fā)編程示例(二):獲取和設(shè)置線程信息

    Java并發(fā)編程示例(二):獲取和設(shè)置線程信息

    這篇文章主要介紹了Java并發(fā)編程示例(二):獲取和設(shè)置線程信息,本文是系列文章的第二篇,本文著重講解Thread類的幾個重要屬性,需要的朋友可以參考下
    2014-12-12
  • Java使用Collections.sort對中文進(jìn)行排序方式

    Java使用Collections.sort對中文進(jìn)行排序方式

    這篇文章主要介紹了Java使用Collections.sort對中文進(jìn)行排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring對事務(wù)管理的支持

    Spring對事務(wù)管理的支持

    今天小編就為大家分享一篇關(guān)于Spring對事務(wù)管理的支持,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • SpringBoot搭Flowable搞工作流的實現(xiàn)示例

    SpringBoot搭Flowable搞工作流的實現(xiàn)示例

    本文主要介紹了SpringBoot搭Flowable搞工作流的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • 深入了解Java?Synchronized鎖升級過程

    深入了解Java?Synchronized鎖升級過程

    java中的鎖是針對對象而言的,它鎖住的是一個對象,并且具有可重入的性質(zhì),下面這篇文章主要給大家介紹了關(guān)于Java?Synchronized鎖升級過程的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • java 對象參數(shù)去空格方式代碼實例

    java 對象參數(shù)去空格方式代碼實例

    這篇文章主要介紹了java 對象參數(shù)去空格方式代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • java實現(xiàn)酷狗音樂臨時緩存文件轉(zhuǎn)換為MP3文件的方法

    java實現(xiàn)酷狗音樂臨時緩存文件轉(zhuǎn)換為MP3文件的方法

    這篇文章主要介紹了java實現(xiàn)酷狗音樂臨時緩存文件轉(zhuǎn)換為MP3文件的方法,涉及java針對文件操作的相關(guān)技巧,需要的朋友可以參考下
    2016-08-08

最新評論

凉城县| 方城县| 新泰市| 通化市| 湟中县| 馆陶县| 平乐县| 岑巩县| 中江县| 南靖县| 图们市| 盘山县| 疏附县| 土默特右旗| 肥西县| 怀仁县| 保山市| 鱼台县| 孙吴县| 宜丰县| 马公市| 花莲市| 左贡县| 延寿县| 商南县| 临夏县| 四会市| 海伦市| 监利县| 西吉县| 南岸区| 东丽区| 温州市| 昭平县| 普安县| 客服| 沙雅县| 淮北市| 石门县| 铁岭市| 徐汇区|