工作中遇到需要将整合后的数据能够按照任意字段进行排序的需求,一定程度上使用动态SQL的方式也实现不了这个功能。而且涉及到的排序字段又比较多,将数据整合好后通过写if-else的方法去逐一字段排序,显得比较呆(好吧,其实是想偷懒),于是在网上查了相关方法。
前提依赖:
commons-beanutils-1.8.3.jar
commons-collections-3.2.1.jar
commnos-logging-1.0.4.jar
举例说明:
//需要排序的对象
public class Student{
private Long id;
private String name;
private int age;
private int score;
}
import org.apache.commons.collections.comparators.ComparableComparator;
//需要排序的对象集合
List<Student> studentList = new ArrayList<>();
//设置排序比较器
Comparator mycmp = ComparableComparator.getInstance();
mycmp = ComparatorUtils.reversedComparator(mycmp);
mycmp = ComparatorUtils.nullHighComparator(mycmp);
//添加要排序的对象属性,并指定排序规则
ArrayList<Object> sortFields = new ArrayList<Object>();
sortFields.add( new BeanComparator("score" , mycmp));
sortFields.add( new BeanComparator("age" , mycmp));
//不指明则用默认排序
sortFields.add( new BeanComparator("score"));
//创建排序链
ComparatorChain multiSort = new ComparatorChain(sortFields);
//按照sortFields中的排序规则的先后顺序,执行排序
Collections.sort (studentList , multiSort);
补充说明:
①通过ComparatorUtils封装好的排序器,可以直接声明是要倒序排,还是正序排(默认是正序,不需要声明),而不需再考虑Comparator返回值。
②通过ComparatorChain排序链的先后添加顺序,可以很方便地指定排序规则的执行顺序。
③通过BeanComparator,直接传参为要排序的字段名称,代码可读性很强,维护起来也很方便。
更新:
依赖的jar包如果引入了 commons-collections4-4.4 版本的,则代码应改为如下示例:在申明比较器时的写法发生变化,其余排序写法都与之前保持一致。
import org.apache.commons.collections4.comparators.ComparableComparator;
//需要排序的对象集合
List<Student> studentList = new ArrayList<>();
//设置排序比较器
Comparator mycmp = ComparableComparator.comparableComparator();
mycmp = ComparatorUtils.reversedComparator(mycmp);
mycmp = ComparatorUtils.nullHighComparator(mycmp);
//添加要排序的对象属性,并指定排序规则
ArrayList<Object> sortFields = new ArrayList<Object>();
sortFields.add( new BeanComparator("score" , mycmp));
sortFields.add( new BeanComparator("age" , mycmp));
//不指明则用默认排序
sortFields.add( new BeanComparator("score"));
//创建排序链
ComparatorChain multiSort = new ComparatorChain(sortFields);
//按照sortFields中的排序规则的先后顺序,执行排序
Collections.sort (studentList , multiSort);
参考文章: