在项目中遇到复杂查询的多样化排序需求,由于得分规则复杂需要临时汇总列表展示的分数...所以分数无法在sql内直接查询得出(复杂计算,并不只是简单的sum求和)
排序需求包含如下:
排序类型:0默认排序,1提交时间升序,2提交时间降序,3成绩升序,4成绩降序,5讨论数降序
其中成绩的排序,上述无法直接sql计算拿到,即无法在分页查询过程中去做,此时只能查出全部再手动分页。
代码段如下:
if (manualPage.contains(order) && pn != null && ps != null) {// 按成绩排序时查全部,重新排序和分页
List newList;
if (order == 3) {
newList = list.stream().sorted(Comparator.comparing(StudentGroupHomeworkDTO::getScore, Comparator.nullsFirst(BigDecimal::compareTo))).collect(Collectors.toList());
} else {
newList = list.stream().sorted(Comparator.comparing(StudentGroupHomeworkDTO::getScore, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()).collect(Collectors.toList());
}
//创建Page类
Page page = new Page<>(pn, ps);
//为Page类中的total属性赋值
int total = newList.size();
page.setTotal(total);
//计算当前需要显示的数据下标起始值
int startIndex = (pn - 1) * ps;
int endIndex = Math.min(startIndex + ps, total);
//从链表中截取需要显示的子链表,并加入到Page
page.addAll(newList.subList(startIndex, endIndex));
//以Page创建PageInfo
PageInfo pageInfo = new PageInfo<>(page);
return pageInfo.getList();
}
按成绩升序/降序时,踩了属性为空导致Comparator.comparing()方法报错了,之前也出现过类似问题,换成了Set排序......
今天打破砂锅问到底,看到有说必须重写Comparator.comparing()的博客,但是如果不为空可以不重写也能正常排序出结果,纠结了一下看有没有更好的方法。查找追溯到stream.sorted源码,发现有Comparator.nullsFirst和Comparator.nullsLast方法:
方法 | 注释 |
Comparator.nullsFirst | 排序字段为null的对象放在排序后的List最后面 |
Comparator.nullsLast | 排序字段为null的对象放在排序后的List最前面 |
使用nullsFirst方法完美解决!