Java 比较器实战

作者: deniro | 来源:发表于2018-08-15 10:00 被阅读69次

    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哈哈~

    相关文章

      本文标题:Java 比较器实战

      本文链接:https://www.haomeiwen.com/subject/kzjibftx.html