1 需求
一个项目, 展示监控数据列表, 数据来源于接口, 不需要分页, 目前可时长排序:
客户希望可先对[状态] 分组, 然后再对[时长] 排序.
2 分析
考虑以下方案:
1. 编写 js 脚本, 在前端做分组排序.
2. 利用 Java 比较器, 在后端做分组排序, 前端直接渲染即可.
比较后发现使用 Java 比较器实现, 更方便些.
3 Java 比较器
Java 中有两种比较器的实现方式: Comparable(内部比较器) 与 Comparator(外部比较器).
3.1 Comparable 接口
代码模板:
- public class Entity implements Comparable<Entity> {
- @Override
- public int compareTo(Entity o) {
- return 0;
- }
- }
Comparable 接口支持泛型参数, 所以一个需要比较实体类只需要按照上面的代码模板实现 Comparable 接口, 即可对传入的另一个同类型的实体类进行比较啦.
因为比较方法是定义在实体类中, 所以把它叫做内部比较器.
3.2 Comparator 接口
代码模板:
- public class EntityComparator implements Comparator<Entity> {
- @Override
- public int compare(Entity o1, Entity o2) {
- return 0;
- }
- }
Comparator 接口同样也支持泛型参数. 不同的是它是一个比较器类, 所以叫它外部比较器. 比较器类使用更灵活, 我们可以定义多个比较器类用于不同的排序场景.
4 实战
因为业务场景需要先对[状态] 分组排序后, 然后再对[时长] 排序, 而[时长] 的排序又可分为正序与逆序两种, 所以我们采用 Java 外部比较器来实现该业务逻辑.
待比较的实体类:
- public class Record {
- // 状态
- private String state;
- // 时长
- private String time;
- public Record(String state, String time) {
- this.state = state;
- this.time = time;
- }
- public String getState() {
- return state;
- }
- public String getTime() {
- return time;
- }
- @Override
- public String toString() {
- return "Record{" +
- "state='" + state + '\'' +
- ", time='" + time + '\'' +
- '}';
- }
- }
比较器 A: 先对[状态] 排序, 然后再对[时长] 按正序排序
- public class RecordComparator implements Comparator<Record> {
- @Override
- public int compare(Record o1, Record o2) {
- final int stateCompare = o1.getState().compareTo(o2.getState());
- if (stateCompare == 0) {
- return o1.getTime().compareTo(o2.getTime());
- }
- return stateCompare;
- }
- }
比较器 B: 先对 [状态] 排序, 然后再对[时长] 按逆序(倒序) 排序
- public class RecordTimeDescComparator implements Comparator<Record> {
- @Override
- public int compare(Record o1, Record o2) {
- final int stateCompare = o1.getState().compareTo(o2.getState());
- if (stateCompare == 0) {
- return o2.getTime().compareTo(o1.getTime());
- }
- return stateCompare;
- }
- }
单元测试:
- Record record1 = new Record("通话中", "00:01:08");
- Record record2 = new Record("空闲", "00:18:02");
- Record record3 = new Record("通话中", "00:04:04");
- Record record4 = new Record("空闲", "00:01:57");
- List<Record> recordList = new ArrayList<>();
- recordList.add(record1);
- recordList.add(record2);
- recordList.add(record3);
- recordList.add(record4);
- System.out.println("排序前:" + recordList);
- Collections.sort(recordList, new RecordComparator());
- System.out.println("排序后[时间正序] :" + recordList);
- recordList = new ArrayList<>();
- recordList.add(record1);
- recordList.add(record2);
- recordList.add(record3);
- recordList.add(record4);
- System.out.println("排序前:" + recordList);
- Collections.sort(recordList, new RecordTimeDescComparator());
- System.out.println("排序后[时间倒序] :" + recordList);
输出结果:
排序前:[Record{state='通话中', time='00:01:08'}, Record{state='空闲', time='00:18:02'}, Record{state='通话中', time='00:04:04'}, Record{state='空闲', time='00:01:57'}]
排序后[时间正序] :[Record{state='空闲', time='00:01:57'}, Record{state='空闲', time='00:18:02'}, Record{state='通话中', time='00:01:08'}, Record{state='通话中', time='00:04:04'}]
排序前:[Record{state='通话中', time='00:01:08'}, Record{state='空闲', time='00:18:02'}, Record{state='通话中', time='00:04:04'}, Record{state='空闲', time='00:01:57'}]
排序后[时间倒序] :[Record{state='空闲', time='00:18:02'}, Record{state='空闲', time='00:01:57'}, Record{state='通话中', time='00:04:04'}, Record{state='通话中', time='00:01:08'}]
通过 Java 比较器就可以把看似复杂的问题解决啦 O(_)O 哈哈~
来源: http://www.jianshu.com/p/ddacf701fdb1