使用Stream流来进行分类展示。
1:首先,先来看我的数据库。
在我的数据库中可以看到,一级分类得parent_id是0,二级分类得parent_id就是他得父类得id
2:目标
我的目标呢,就是要通过流式编程要将一级分类和二级分类整合到一起,也就是要将二级分类放到一级分类中得children 属性中,然后返回给前端。
3:解决办法
(1)第一种
思路就是,单独创建两个类,一个一级分类,一个二级分类,,然后使用MP,分别获取到所有得一级分类和所有得二级分类,在这里,因为后台返回得是表中所有得字段,而不是我们所要得字段,所以需要单独去赋值。
//一级分类
@Data
@Accessors(chain = true)
public class OneSubject {
private String id;
private String title;
//一个一级分类有多个二级分类
private List<TwoSubject> children=new ArrayList<>();
}
//二级分类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TwoSubject {
private String id;
private String title;
}
Java代码实现
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
//将一级分类和二级分类放到一起
@Override
public List<OneSubject> getAllOneTwoSubject() {
//查询所有一级分类 parentid=0
QueryWrapper<EduSubject> wrapperOne = new QueryWrapper<>();
wrapperOne.eq("parent_id","0");
List<EduSubject> oneSubjectList = baseMapper.selectList(wrapperOne);
//查询所有二级分类 parentid!=0
QueryWrapper<EduSubject> wrapperTwo = new QueryWrapper<>();
wrapperOne.ne("parent_id","0");
List<EduSubject> twoSubjectList = baseMapper.selectList(wrapperTwo);
//创建list集合,用于存放最终封装的数据
List<OneSubject> finalSubjectList=new ArrayList<>();
//封装一级分类
//查询出来所有的一级分类list集合遍历,得到每一级分类对象,获得每个一级分类对象值
//封装到要求的list集合里面
for (int i = 0; i < oneSubjectList.size(); i++) {
EduSubject eduSubject = oneSubjectList.get(i);
OneSubject oneSubject = new OneSubject();
// oneSubject.setId(eduSubject.getId());
// oneSubject.setTitle(eduSubject.getTitle());
//把eduSubject值复制到对应的oneSubject对象里面,两个对象里面的属性相同对应的的自动赋值
BeanUtils.copyProperties(eduSubject,oneSubject);
//在一级分类循环遍历查询所有的二级分类
//创建list集合封装每个一级分类的二级分类
List<TwoSubject> twoFinalSubjectList=new ArrayList<>();
//遍历二级分类list集合
for (int j = 0; j < twoSubjectList.size(); j++) {
EduSubject tSubject = twoSubjectList.get(j);
//如果二级分类的parentid和一级分类的id一样,就把它加入到一级分类
if(tSubject.getParentId().equals(eduSubject.getId())){
TwoSubject twoSubject = new TwoSubject();
BeanUtils.copyProperties(tSubject,twoSubject);
twoFinalSubjectList.add(twoSubject);
}
}
//把一级下面所有的二级分类放到一级分类里面
oneSubject.setChildren(twoFinalSubjectList);
finalSubjectList.add(oneSubject);
}
return finalSubjectList;
}
}
(2)第二种
①:第二种方法使用流式编程,也就是我们今天得主题。
思路:这里不用创建类型,在数据库返回得接收字段中 新增一个 字段。创建一个Stream流,然后在map方法中设置他的二级分类,也就是children. 在这里定义一个方法,就是为了获取某一个一级分类下面得所有二级分类,然后返回所有二级分类,然后加到一级分类得children属性中。
@TableField(exist = false)//该字段在数据库中并不存在
private List<EduSubject> children;
Java代码实现
//将一级分类和二级分类放到一起
@Override
public List<EduSubject> getAllOneTwoSubject() {
//查询所有一级分类 parentid=0
QueryWrapper<EduSubject> wrapperOne = new QueryWrapper<>();
wrapperOne.eq("parent_id", "0");
List<EduSubject> oneSubjectList = baseMapper.selectList(wrapperOne);
//查询所有二级分类 parentid!=0
QueryWrapper<EduSubject> wrapperTwo = new QueryWrapper<>();
wrapperOne.ne("parent_id", "0");
List<EduSubject> twoSubjectList = baseMapper.selectList(wrapperTwo);
//此时已经拿到了一级分类(oneSubjectList)和二级分类(twoSubjectList),
//1:采用流式编程将二级分类中得数据封装到一级分类中得children中
oneSubjectList.stream()
.map(sub ->{
return sub.setChildren(getChildren(sub.getId(),twoSubjectList));
})
.collect(Collectors.toList());
return oneSubjectList;
}
// //判断一级父类中得二级分类
@Override
public List<EduSubject> getChildren(String oneSubject, List<EduSubject> eduSubject) {
return eduSubject.stream().filter(res -> {return res.getParentId().equals(oneSubject);}).collect(Collectors.toList());
}
②:创建实体类,不在原来类中去改变。
@Override
public List<ChapterVo> getChapterVideoByCourseId(String courseId) {
//根据课程id查询课程里面所有章节
QueryWrapper<EduChapter> eduChapterQueryWrapper = new QueryWrapper<EduChapter>();
eduChapterQueryWrapper.eq("course_id",courseId);
List<EduChapter> eduChapterList = baseMapper.selectList(eduChapterQueryWrapper);
//根据课程id查询课程里面所有的小节
QueryWrapper<EduVideo> eduVideoQueryWrapper = new QueryWrapper<>();
eduVideoQueryWrapper.eq("course_id",courseId);
List<EduVideo> eduVideoList = videoService.list(eduVideoQueryWrapper);
//创建一个最终得返回集合
List<ChapterVo> finalList = new ArrayList<>();
eduChapterList.stream()
.map(res ->{
ChapterVo chapterVo = new ChapterVo();
//将res对象属性set给chapterVo
BeanUtils.copyProperties(res,chapterVo);
chapterVo.setChildren(
eduVideoList.stream()
//根据id进行判断过滤
.filter(ress ->{return chapterVo.getId().equals(ress.getChapterId());})
.map(ressss ->{
VideoVo videoVo = new VideoVo();
BeanUtils.copyProperties(ressss,videoVo);
return videoVo;
})
.collect(Collectors.toList())
);
finalList.add(chapterVo);
return chapterVo;
})
.collect(Collectors.toList());
return finalList;
}
绝命Coding: 欢迎大佬来交流,【大厂面试官问我:Redis处理点赞,如果瞬时涌入大量用户点赞(千万级),应当如何进行处理?【后端八股文一:Redis点赞八股文合集】 - CSDN App】http://t.csdnimg.cn/v7t8i
小泽不会Java: 不要客气,一起成长哦
耗子喂汁: 对,很奇怪
小泽不会Java: 你也报错了吗
耗子喂汁: 看案例应该是黑马教程,明明版本都一样,怎么老师就没报错呢....