java返回前端樹(shù)形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式
0.思想
首先找到一級(jí)目錄(類(lèi)別),然后從一級(jí)目錄(類(lèi)別)遞歸獲取所有子目錄(類(lèi)別),并組合成為一個(gè)“目錄樹(shù)”
1.普通實(shí)現(xiàn):
controller層傳的是0層,就是一級(jí)目錄層,從這里開(kāi)始往下遞歸。
/** * 遞歸查詢(xún)得到,分類(lèi)目錄數(shù)據(jù);(針對(duì)前臺(tái)的) * @return */ @Override public List<CategoryVO> listCategoryForCustomer() { //定義一個(gè)List,這個(gè)List就用來(lái)存在最終的查詢(xún)結(jié)果;即,這個(gè)List中的直接元素是:所有的parent_id=0,即type=1的,第1級(jí)別的目錄; List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>(); //我們額外創(chuàng)建recursivelyFindCategories()方法,去實(shí)現(xiàn)遞歸查詢(xún)的邏輯; //我們第一次遞歸查詢(xún)時(shí),是先查一級(jí)目錄;(而一級(jí)目錄的parentId是0) //該方法第一個(gè)參數(shù)是:List<CategoryVO> categoryVOList:用來(lái)存放當(dāng)前級(jí)別對(duì)應(yīng)的,所有的下一級(jí)目錄數(shù)據(jù); // PS:對(duì)于【最終返回給前端的List<CategoryVO> categoryVOList】來(lái)說(shuō),其所謂的下一級(jí)目錄就是:所有的parent_id=0,即type=1的,第1級(jí)別的目錄; // PS:對(duì)于【所有的parent_id=0,即type=1的,第1級(jí)別的目錄;】來(lái)說(shuō),其categoryVOList就是【List<CategoryVO> childCategory屬性】,其是用來(lái)存放該級(jí)別對(duì)應(yīng)的所有的parent_id=1,即type=2的,第2級(jí)別的目錄; // PS:對(duì)于【所有的parent_id=1,即type=2的,第2級(jí)別的目錄;】來(lái)說(shuō),其categoryVOList就是【List<CategoryVO> childCategory屬性】,其是用來(lái)存放該級(jí)別對(duì)應(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; } /** * 遞歸查詢(xún)分類(lèi)目錄數(shù)據(jù)的,具體邏輯;;;其實(shí)就是,遞歸獲取所有目錄分類(lèi)和子目錄分類(lèi),并組合稱(chēng)為一個(gè)“目錄樹(shù)”; * @param categoryVOList :存放所有下級(jí)別分類(lèi)目錄的數(shù)據(jù); * @param parentId :某級(jí)分類(lèi)目錄的parentId; */ private void recursivelyFindCategories(List<CategoryVO> categoryVOList, Integer parentId) { //首先,根據(jù)parent_id,查詢(xún)出所有該級(jí)別的數(shù)據(jù);(比如,第一次我們查詢(xún)的是parent_id=0,即type=1的,第1級(jí)別的目錄) List<Category> categoryList = categoryMapper.selectCategoriesByParentId(parentId); //然后,遍歷上面查詢(xún)的該級(jí)別的數(shù)據(jù);去嘗試查詢(xún)?cè)摷?jí)別數(shù)據(jù)的,下一級(jí)別的數(shù)據(jù); if (!CollectionUtils.isEmpty(categoryList)) { //遍歷所有查到的當(dāng)前級(jí)別數(shù)據(jù),把其放在對(duì)應(yīng)上級(jí)目錄的【List<CategoryVO> categoryVOList】中; for (int i = 0; i < categoryList.size(); i++) { //獲取到【上面查詢(xún)的,該級(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)鍵:針對(duì)【每一個(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.查出所有分類(lèi) List<Category> categories = categoryMapper.selectList(); //轉(zhuǎn)成VO實(shí)體集合類(lèi) List<CategoryVO> categoryVOS = new ArrayList<>(); //ArrayListBeanUtils.copyProperties(categories,categoryVOS); //注意BeanUtils.copyProperties無(wú)法直接復(fù)制集合,要循環(huán);也可以單獨(dú)寫(xiě)一個(gè)工具類(lèi), //后續(xù)補(bǔ)充轉(zhuǎn)換集合工具類(lèi) for (Category category:categories ) { CategoryVO categoryVO = new CategoryVO(); BeanUtils.copyProperties(category,categoryVO); categoryVOS.add(categoryVO); } //2.組裝成父子的樹(shù)形結(jié)構(gòu) //2.1 找到所有的一級(jí)分類(lèi) List<CategoryVO> collect = categoryVOS.stream().filter(categoryVO -> { return categoryVO.getParentId() == 0;//一級(jí)分類(lèi)就是父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í)體類(lèi)集合專(zhuān)VO類(lèi)集合的工具類(lèi)
入?yún)槲粗?lèi)型的實(shí)體集合與目標(biāo)集合的泛型字節(jié)碼類(lèi)型(類(lèi)名.class)
創(chuàng)建一個(gè)新集合用來(lái)存儲(chǔ)最終結(jié)果,泛型為目標(biāo)類(lèi)型T
遍歷循環(huán)實(shí)體集合
通過(guò)Class獲取構(gòu)造器并創(chuàng)建新的實(shí)例
使用BeanUtils.copyProperties,將實(shí)體數(shù)據(jù)拷貝到目標(biāo)類(lèi)型
將拷貝過(guò)數(shù)據(jù)的目標(biāo)類(lèi)型添加到集合中
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返回前端樹(shù)形結(jié)構(gòu)數(shù)據(jù)的2種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)java返回前端樹(shù)形結(jié)構(gòu)數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java如何使用遞歸查詢(xún)多級(jí)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(多級(jí)菜單)
- Java使用 Stream 流和 Lambda 組裝復(fù)雜父子樹(shù)形結(jié)構(gòu)
- java+vue3+el-tree實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)操作代碼
- 詳解如何使用Java流API構(gòu)建樹(shù)形結(jié)構(gòu)數(shù)據(jù)
- java如何讀取文件目錄返回樹(shù)形結(jié)構(gòu)
- Java中如何將list轉(zhuǎn)為樹(shù)形結(jié)構(gòu)
- Java樹(shù)形結(jié)構(gòu)遞歸查詢(xún)方式
相關(guān)文章
Java數(shù)組中的元素刪除并實(shí)現(xiàn)向前移的代碼
這篇文章主要介紹了Java數(shù)組中的元素刪除并實(shí)現(xiàn)向前移的代碼的相關(guān)資料,需要的朋友可以參考下2016-05-05Java實(shí)現(xiàn)查找算法的示例代碼(二分查找、插值查找、斐波那契查找)
查找就是根據(jù)給定的某個(gè)值,在查找表中確定一個(gè)其關(guān)鍵字等于給定值的數(shù)據(jù)元素。本文介紹了常見(jiàn)的數(shù)據(jù)查找算法:順序查找、二分查找、插值查找和斐波那契查找等以及相應(yīng)的Java代碼實(shí)現(xiàn)。需要的可以參考一下2022-01-01Java的動(dòng)態(tài)綁定與雙分派_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java的動(dòng)態(tài)綁定與雙分派,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08劍指Offer之Java算法習(xí)題精講鏈表與數(shù)組專(zhuān)項(xiàng)訓(xùn)練
跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過(guò)之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化2022-03-03IDEA啟動(dòng)Springboot報(bào)錯(cuò):無(wú)效的目標(biāo)發(fā)行版:17 的解決辦法
這篇文章主要給大家介紹了IDEA啟動(dòng)Springboot報(bào)錯(cuò):無(wú)效的目標(biāo)發(fā)行版:17 的解決辦法,文中通過(guò)代碼示例和圖文講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02基于idea操作hbase數(shù)據(jù)庫(kù)并映射到hive表
這篇文章主要介紹了用idea操作hbase數(shù)據(jù)庫(kù),并映射到hive,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03SpringBoot實(shí)現(xiàn)自定義指標(biāo)監(jiān)控功能
本文主要介紹了SpringBoot實(shí)現(xiàn)自定義指標(biāo)監(jiān)控功能的實(shí)現(xiàn),,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,感興趣的小伙伴跟著著小編來(lái)一起來(lái)學(xué)習(xí)吧2024-01-01