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

java返回前端樹形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式

 更新時(shí)間:2024年05月25日 11:07:54   作者:陽光不銹@  
近期項(xiàng)目有個(gè)需求,需要將組織機(jī)構(gòu)數(shù)據(jù)拼成樹型結(jié)構(gòu)返回至前端,下面這篇文章主要給大家介紹了關(guān)于java返回前端樹形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

0.思想

首先找到一級(jí)目錄(類別),然后從一級(jí)目錄(類別)遞歸獲取所有子目錄(類別),并組合成為一個(gè)“目錄樹”

1.普通實(shí)現(xiàn):

controller層傳的是0層,就是一級(jí)目錄層,從這里開始往下遞歸。

/**
     * 遞歸查詢得到,分類目錄數(shù)據(jù);(針對前臺(tái)的)
     * @return
     */
    @Override
    public List<CategoryVO> listCategoryForCustomer() {
        //定義一個(gè)List,這個(gè)List就用來存在最終的查詢結(jié)果;即,這個(gè)List中的直接元素是:所有的parent_id=0,即type=1的,第1級(jí)別的目錄;
        List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
 
        //我們額外創(chuàng)建recursivelyFindCategories()方法,去實(shí)現(xiàn)遞歸查詢的邏輯;
        //我們第一次遞歸查詢時(shí),是先查一級(jí)目錄;(而一級(jí)目錄的parentId是0)
        //該方法第一個(gè)參數(shù)是:List<CategoryVO> categoryVOList:用來存放當(dāng)前級(jí)別對應(yīng)的,所有的下一級(jí)目錄數(shù)據(jù);
        //  PS:對于【最終返回給前端的List<CategoryVO> categoryVOList】來說,其所謂的下一級(jí)目錄就是:所有的parent_id=0,即type=1的,第1級(jí)別的目錄;
        //  PS:對于【所有的parent_id=0,即type=1的,第1級(jí)別的目錄;】來說,其categoryVOList就是【List<CategoryVO> childCategory屬性】,其是用來存放該級(jí)別對應(yīng)的所有的parent_id=1,即type=2的,第2級(jí)別的目錄;
        //  PS:對于【所有的parent_id=1,即type=2的,第2級(jí)別的目錄;】來說,其categoryVOList就是【List<CategoryVO> childCategory屬性】,其是用來存放該級(jí)別對應(yīng)的所有的parent_id=2,即type=3的,第3級(jí)別的目錄;
        //該方法的第二個(gè)參數(shù)是:當(dāng)前級(jí)別目錄的parent_id,即也就是當(dāng)前級(jí)別的上一級(jí)目錄的id;
        //即,第一個(gè)參數(shù)是【上一級(jí)別的List<CategoryVO> categoryVOList】;第二參數(shù)是【下一級(jí)別的parent_id,也就是當(dāng)前級(jí)別的id】;
        recursivelyFindCategories(categoryVOList, 0);
        return categoryVOList;
    }
 
    /**
     * 遞歸查詢分類目錄數(shù)據(jù)的,具體邏輯;;;其實(shí)就是,遞歸獲取所有目錄分類和子目錄分類,并組合稱為一個(gè)“目錄樹”;
     * @param categoryVOList :存放所有下級(jí)別分類目錄的數(shù)據(jù);
     * @param parentId :某級(jí)分類目錄的parentId;
     */
    private void recursivelyFindCategories(List<CategoryVO> categoryVOList, Integer parentId) {
        //首先,根據(jù)parent_id,查詢出所有該級(jí)別的數(shù)據(jù);(比如,第一次我們查詢的是parent_id=0,即type=1的,第1級(jí)別的目錄)
        List<Category> categoryList = categoryMapper.selectCategoriesByParentId(parentId);
        //然后,遍歷上面查詢的該級(jí)別的數(shù)據(jù);去嘗試查詢該級(jí)別數(shù)據(jù)的,下一級(jí)別的數(shù)據(jù);
        if (!CollectionUtils.isEmpty(categoryList)) {
            //遍歷所有查到的當(dāng)前級(jí)別數(shù)據(jù),把其放在對應(yīng)上級(jí)目錄的【List<CategoryVO> categoryVOList】中;
            for (int i = 0; i < categoryList.size(); i++) {
                //獲取到【上面查詢的,該級(jí)別數(shù)據(jù)中的,一條數(shù)據(jù)】,把其存儲(chǔ)到上級(jí)目錄的List<CategoryVO> childCategory屬性中;
                //自然,如果該級(jí)別是【parent_id=0,即type=1的,第1級(jí)別的目錄】,就是把其存儲(chǔ)在最頂級(jí)的、返回給前端的那個(gè)List<CategoryVO> categoryVOS中;
                Category category =  categoryList.get(i);
                CategoryVO categoryVo = new CategoryVO();
                BeanUtils.copyProperties(category, categoryVo);
                categoryVOList.add(categoryVo);
 
                //然后,這一步是關(guān)鍵:針對【每一個(gè)當(dāng)前級(jí)別的,目錄數(shù)據(jù)】去遞歸調(diào)用recursivelyFindCategories()方法;
                //自然,第一個(gè)參數(shù)是【當(dāng)前級(jí)別數(shù)據(jù)的,List<CategoryVO> childCategory屬性】:這是存放所有下級(jí)別目錄數(shù)據(jù)的;
                //第二個(gè)參數(shù)是【當(dāng)前級(jí)別數(shù)據(jù)的id】:這自然是下級(jí)別目錄數(shù)據(jù)的parent_id:
                recursivelyFindCategories(categoryVo.getChildCategory(), categoryVo.getId());
            }
        }
    }

2.stream流實(shí)現(xiàn):

  /**
     * 利用stream 流實(shí)現(xiàn)
     *
     */
    @Override
    public List<CategoryVO> listTree() {
        //1.查出所有分類
        List<Category> categories = categoryMapper.selectList();
        //轉(zhuǎn)成VO實(shí)體集合類
        List<CategoryVO> categoryVOS = new ArrayList<>();
        //ArrayListBeanUtils.copyProperties(categories,categoryVOS);
        //注意BeanUtils.copyProperties無法直接復(fù)制集合,要循環(huán);也可以單獨(dú)寫一個(gè)工具類,
        //后續(xù)補(bǔ)充轉(zhuǎn)換集合工具類
        for (Category category:categories
             ) {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(category,categoryVO);
            categoryVOS.add(categoryVO);
        }
        //2.組裝成父子的樹形結(jié)構(gòu)
        //2.1 找到所有的一級(jí)分類
        List<CategoryVO> collect = categoryVOS.stream().filter(categoryVO -> {
            return categoryVO.getParentId() == 0;//一級(jí)分類就是父id=0是吧
        }).map(menu -> {
            menu.setChildCategory(getChildrens(menu,categoryVOS));
            return menu;
        }).sorted((menu1,menu2)->{//目錄排序
            return (menu1.getOrderNum() ==null?0:menu1.getOrderNum() )- (menu2.getOrderNum() == null?0:menu2.getOrderNum());
        }).collect(Collectors.toList());

        return collect;
    }

    //遞歸查找所有菜單的子菜單
    //root 當(dāng)前菜單,categoryList是菜單集合
    private List<CategoryVO> getChildrens(CategoryVO root, List<CategoryVO> categoryList) {
        //找出當(dāng)前菜單的子菜單
        List<CategoryVO> children = categoryList.stream().filter(categoryVO -> {
            //當(dāng)前菜單root的id等于(是)菜單集合中菜單的父Id,那就意味著當(dāng)前菜單就是子菜單
            //當(dāng)前菜單root的id,是其他菜單的父id,意味著當(dāng)前菜單的子菜單找到了唄
            return categoryVO.getParentId() == root.getId();
        }).map(categoryVO -> {
            //找到子菜單
            categoryVO.setChildCategory(getChildrens(categoryVO, categoryList));
            return categoryVO;
        }).sorted((menu1,menu2)->{
            //菜單的排序
            return (menu1.getOrderNum() ==null?0:menu1.getOrderNum() )- (menu2.getOrderNum() == null?0:menu2.getOrderNum());
        }).collect(Collectors.toList());

        return children;
    }

3.實(shí)體類集合專VO類集合的工具類

入?yún)槲粗愋偷膶?shí)體集合與目標(biāo)集合的泛型字節(jié)碼類型(類名.class)

創(chuàng)建一個(gè)新集合用來存儲(chǔ)最終結(jié)果,泛型為目標(biāo)類型T

遍歷循環(huán)實(shí)體集合

通過Class獲取構(gòu)造器并創(chuàng)建新的實(shí)例

使用BeanUtils.copyProperties,將實(shí)體數(shù)據(jù)拷貝到目標(biāo)類型

將拷貝過數(shù)據(jù)的目標(biāo)類型添加到集合中

public static <T> List<T> entityListToVOList(List<?> list, Class<T> clazz) {
    List<T> result = new ArrayList<>(list.size());
    for (Object source : list) {
        T target;
        try {
            target = clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException();
        }
        BeanUtils.copyProperties(source, target);
        result.add(target);
    }
    return result;
}

總結(jié)  

到此這篇關(guān)于java返回前端樹形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)java返回前端樹形結(jié)構(gòu)數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)簡易圖書借閱系統(tǒng)

    Java實(shí)現(xiàn)簡易圖書借閱系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡易圖書借閱系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Spring?Boot?2.x升3.x的那些事

    Spring?Boot?2.x升3.x的那些事

    最近項(xiàng)目需求,準(zhǔn)備從Spring Boot 2.x升級(jí)到3.x,升級(jí)后發(fā)現(xiàn)編譯器報(bào)了一堆錯(cuò)誤,本文主要介紹了Spring?Boot?2.x升3.x的那些事,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Zuul實(shí)現(xiàn)動(dòng)態(tài)路由與權(quán)限過濾器方式

    Zuul實(shí)現(xiàn)動(dòng)態(tài)路由與權(quán)限過濾器方式

    文章介紹如何通過Zuul實(shí)現(xiàn)動(dòng)態(tài)路由與權(quán)限驗(yàn)證,利用自定義過濾器和配置刷新機(jī)制,提升系統(tǒng)靈活性與安全性,確保接口訪問可控且無需重啟
    2025-07-07
  • java數(shù)據(jù)結(jié)構(gòu)和算法中哈希表知識(shí)點(diǎn)詳解

    java數(shù)據(jù)結(jié)構(gòu)和算法中哈希表知識(shí)點(diǎn)詳解

    在本篇文章里小編給大家分享了關(guān)于java數(shù)據(jù)結(jié)構(gòu)和算法中哈希表的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的朋友們學(xué)習(xí)下。
    2019-06-06
  • MyBatisPlus+Lombok實(shí)現(xiàn)分頁功能的方法詳解

    MyBatisPlus+Lombok實(shí)現(xiàn)分頁功能的方法詳解

    Lombok是一個(gè)Java類庫,提供了一組注解,簡化POJO實(shí)體類開發(fā)。本文將為大家介紹一下Lombok的使用以及如何利用MyBatisPlus+Lombok實(shí)現(xiàn)分頁功能,感興趣的可以動(dòng)手嘗試一下
    2022-07-07
  • Spring結(jié)合WebSocket實(shí)現(xiàn)實(shí)時(shí)通信的教程詳解

    Spring結(jié)合WebSocket實(shí)現(xiàn)實(shí)時(shí)通信的教程詳解

    WebSocket?是基于TCP/IP協(xié)議,獨(dú)立于HTTP協(xié)議的通信協(xié)議,本文將使用Spring結(jié)合WebSocket實(shí)現(xiàn)實(shí)時(shí)通信功能,有需要的小伙伴可以參考一下
    2024-01-01
  • Spring中Bean注入源碼示例解析

    Spring中Bean注入源碼示例解析

    這篇文章主要為大家介紹了Spring中Bean注入源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • SpringBoot實(shí)現(xiàn)郵件發(fā)送功能的姿勢分享

    SpringBoot實(shí)現(xiàn)郵件發(fā)送功能的姿勢分享

    我們在日常開發(fā)中,經(jīng)常會(huì)碰到email郵件發(fā)送的場景,如發(fā)送驗(yàn)證碼,向客戶發(fā)送郵件等等,這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)郵件發(fā)送的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • 解析Java的JVM以及類與對象的概念

    解析Java的JVM以及類與對象的概念

    這篇文章主要介紹了解析Java的JVM以及類與對象的概念,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • 詳解Spring配置文件中bean的相關(guān)屬性

    詳解Spring配置文件中bean的相關(guān)屬性

    這篇文章主要為大家詳細(xì)介紹了Spring配置文件中bean的相關(guān)屬性的知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12

最新評(píng)論

调兵山市| 涟源市| 安西县| 灵川县| 循化| 河池市| 鄂尔多斯市| 镇雄县| 体育| 藁城市| 合肥市| 柯坪县| 古浪县| 自治县| 贵阳市| 绍兴市| 巴彦淖尔市| 桂东县| 乌兰察布市| 黄陵县| 新宁县| 乐平市| 和龙市| 新密市| 玉田县| 三台县| 白城市| 仲巴县| 安仁县| 太仓市| 和政县| 龙山县| 芷江| 台前县| 银川市| 沾化县| 汾阳市| 东方市| 清水县| 高陵县| 黔南|