参考
简介
在跟着尚硅谷学习谷粒商城中遇到这个三级分类问题,使用了Stream
Api,记录一下
过程
主要内容就是对商品类别表进行三级分类,category表设计如下,主要关注,分类id,父分类id,排序这几个字段
数据内容,这里只贴了30条,总1000条,随后在web上展示
了解了需求,CategoryEntity
如下,关注新加入的非数据库字段属性List<CategoryEntity> children
,用于存放该分类下的子分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| @Data @TableName("pms_category") public class CategoryEntity implements Serializable { private static final long serialVersionUID = 1L;
@TableId private Long catId;
private String name;
private Long parentCid;
private Integer catLevel;
private Integer showStatus;
private Integer sort;
private String icon;
private String productUnit;
private Integer productCount;
@TableField(exist = false) private List<CategoryEntity> children;
}
|
我们重点关注业务层,dao层使用的是Mybatis-Plus,不多介绍
就是在这里我们使用了Stream处理了从数据库查到的所有分类信息
处理过程:
- 从数据库查到所有分类信息
List<CategoryEntity>
- 先查到所有的一级分类(
parentCid
为0的,从上面的数据内容也可看出来)
- 接着从这些父分类,找到属于他的子分类(通过
getChildren
函数)
sorted
根据sort字段升序排列
collect
形成集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| @Service("categoryService") public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
...
@Override public List<CategoryEntity> listWithTree() { List<CategoryEntity> entities = baseMapper.selectList(null);
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; }
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查看相关信息
结果就是我们期望的结果,观察发现排序也正确,“手机”排在首位
思考
如果这个业务不使用Stream该怎么做,会有多复杂,从这里就可体会到Stream的强大
使用Stream,需要哪些知识?
首先作为JDK1.8的重点升级,JDK1.8的lambda表达式、函数式接口、链式编程都是重点
四大函数式接口
这些都可以直接搜源码看接口怎样设计的就明白怎么用了,下面我用白话概括一下
Function 函数式接口
传入一个参数,由这个参数返回值
Predicate 断言型接口
传入一个参数,由这个参数进行判断,返回布尔值
Consumer 消费型接口
传入一个参数,由这个参数进行处理,无返回
Supplier 供给型接口
无参数,返回一个值
回想
在使用Stream其实就是传入一些函数式接口,再结合使用lambda表达式就变得非常简便
想想但是学的使用体会还没有这么大,直到遇见了真的业务,感受就马上不同了
总结
此后,我终于能体会到一些算法题的业务场景了,还有JavaSE基础真的很重要,更多的得慢慢感受了