项目场景:
业 务 需 求:分页展示,按照数量倒叙排列
返回的数据类型:List<ObjectVo>
注 意:ObjectVo继承了ObjectPo,并且Po中实现了Comparable接口重写了compareTo方法用于实现按时间
排序,因此vo中不能通过重写compareTo实现数量的排序。
问题描述
遇到的问题:
一、在我有限的经验中学会使用的三种排序是 1、sql中的order by; 2、stream流的sorted方法; 3、实现Comparable接口; 4、外部比较器Comparator
二、因为业务需求和一些其他原因,本文只能通过sorted方法和外部比较器的方法实现
三、在使用sorted方法后发现分页失效了,因此通过外部比较器来实现。
//sorted方法,分页功能失效
list.stream().sorted(Comparator.comparing(ObjectVo::getNum).reversed())
//外部比较器Comparator
//(分为两种方法,一种是创建Comparator比较器,另一种是匿名内部类方式)
// 方式二更简单,本文使用匿名内部类方式
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(objectVo vo1, objectVo vo2) {
return vo2.getNum() - vo1.getNum();
}
});
原因分析:
stream流处理后集合后分页失效的原因:
1、跟踪代码可以发现,在调用mapper接口后返回的数据是一个Page类型的集合。
(也就是说,当我们开启分页后,从数据库查询返回的数据是已经包装好的具有分页属性的数据)
2、再看看stream流处理后的数据,Page属性消失了,此时已经转变成了ArrayList集合,因此分页效果失效
3、原因
分页处理会先判断集合是否为Page类型,是的话转为Page对象,获取已传入的pageNum和pageSize从而实现分页;若不是,则将当前页数pageNum设为1,每页记录数pageSize为集合大小
解决方案:
使用外部比较器Comparator实现排序,或者手动分页
protected TableDataInfo getDataTable(List<?> list) {
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setRows(list);
rspData.setTotal(new PageInfo(list).getTotal());
return rspData;
}
拓展记忆:
Comparable与Comparator的区别
1、Comparable可以看作内部比较器,在创建实体类如vo时,实现Comparable接口,并重写compareTo方法,排序时调用Collections.sort(list)即可。
2、Comparator,而Comparator则是外部比较器,不需要创建时生成,只需要在排序时使用匿名内部类方式排序即可。
参考链接:
https://blog.csdn.net/qq_33492197/article/details/124734863