參考
簡介
在跟著尚硅谷學(xué)習(xí)谷粒商城中遇到這個(gè)三級(jí)分類問題,使用了Stream Api,記錄一下
過程
主要內(nèi)容就是對(duì)商品類別表進(jìn)行三級(jí)分類,category表設(shè)計(jì)如下,主要關(guān)注,分類id,父分類id,排序這幾個(gè)字段

數(shù)據(jù)內(nèi)容,這里只貼了30條,總1000條,隨后在web上展示

了解了需求,CategoryEntity如下,關(guān)注新加入的非數(shù)據(jù)庫字段屬性List<CategoryEntity> children,用于存放該分類下的子分類
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 分類id
*/
@TableId
private Long catId;
/**
* 分類名稱
*/
private String name;
/**
* 父分類id
*/
private Long parentCid;
/**
* 層級(jí)
*/
private Integer catLevel;
/**
* 是否顯示[0-不顯示,1顯示]
*/
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 圖標(biāo)地址
*/
private String icon;
/**
* 計(jì)量單位
*/
private String productUnit;
/**
* 商品數(shù)量
*/
private Integer productCount;
/**
* 子分類
*/
@TableField(exist = false)
private List<CategoryEntity> children;
}
我們重點(diǎn)關(guān)注業(yè)務(wù)層,dao層使用的是Mybatis-Plus,不多介紹
就是在這里我們使用了Stream處理了從數(shù)據(jù)庫查到的所有分類信息
處理過程:
- 從數(shù)據(jù)庫查到所有分類信息
List<CategoryEntity> - 先查到所有的一級(jí)分類(
parentCid為0的,從上面的數(shù)據(jù)內(nèi)容也可看出來) - 接著從這些父分類,找到屬于他的子分類(通過
getChildren函數(shù)) -
sorted根據(jù)sort字段升序排列 -
collect形成集合
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
...
@Override
public List<CategoryEntity> listWithTree() {
// 1、查出所有分類
List<CategoryEntity> entities = baseMapper.selectList(null);
// 2、組裝樹形結(jié)構(gòu)
// 2.1、一級(jí)分類
List<CategoryEntity> level1Menu = entities.stream().filter((categoryEntity) ->
categoryEntity.getParentCid() == 0
).peek((menu) ->
menu.setChildren(getChildren(menu, entities))
).sorted(
Comparator.comparingInt(CategoryEntity::getSort)
).collect(Collectors.toList());
return level1Menu;
}
/**
* 遞歸查找所有菜單的子菜單
* @param root
* @param all
* @return
*/
private List<CategoryEntity> getChildren(CategoryEntity root, List<CategoryEntity> all) {
List<CategoryEntity> children = all.stream().filter((categoryEntity ->
categoryEntity.getParentCid().equals(root.getCatId()))
).peek((categoryEntity ->
categoryEntity.setChildren(getChildren(categoryEntity, all)))
).sorted(
Comparator.comparingInt(CategoryEntity::getSort)
).collect(Collectors.toList());
return children;
}
...
}
最后web顯示如下,我使用的JSONView插件,也可以用F12查看相關(guān)信息

結(jié)果就是我們期望的結(jié)果,觀察發(fā)現(xiàn)排序也正確,“手機(jī)”排在首位
思考
如果這個(gè)業(yè)務(wù)不使用Stream該怎么做,會(huì)有多復(fù)雜,從這里就可體會(huì)到Stream的強(qiáng)大
使用Stream,需要哪些知識(shí)?
首先作為JDK1.8的重點(diǎn)升級(jí),JDK1.8的lambda表達(dá)式、函數(shù)式接口、鏈?zhǔn)骄幊潭际侵攸c(diǎn)
四大函數(shù)式接口
這些都可以直接搜源碼看接口怎樣設(shè)計(jì)的就明白怎么用了,下面我用白話概括一下
Function 函數(shù)式接口
傳入一個(gè)參數(shù),由這個(gè)參數(shù)返回值
Predicate 斷言型接口
傳入一個(gè)參數(shù),由這個(gè)參數(shù)進(jìn)行判斷,返回布爾值
Consumer 消費(fèi)型接口
傳入一個(gè)參數(shù),由這個(gè)參數(shù)進(jìn)行處理,無返回
Supplier 供給型接口
無參數(shù),返回一個(gè)值
回想
在使用Stream其實(shí)就是傳入一些函數(shù)式接口,再結(jié)合使用lambda表達(dá)式就變得非常簡便
想想但是學(xué)的使用體會(huì)還沒有這么大,直到遇見了真的業(yè)務(wù),感受就馬上不同了
總結(jié)
此后,我終于能體會(huì)到一些算法題的業(yè)務(wù)場(chǎng)景了,還有JavaSE基礎(chǔ)真的很重要,更多的得慢慢感受了