• Java Comparable 和 Comparator


    关于Comparable和Comparator

    这篇文章参考Java Sorting: Comparator vs Comparable TutorialJava排序: Comparator vs Comparable 入门做了一些个人总结。

    Comaprable

    一个实现了comparable接口的对象的实例可以被用于和相同对象的不同实例做对比。它本身必须实现java.lang.Comparable的接口,这样它就拥有了对比的能力。即实现了Comparable的对象具有对比的能力。

    Comparator

    一个Comparetor对象能够对比不同的对象,它比较的不是自身的对象——Comparator本身,而是对比其他类的对象。一个Comparator对象必须实现java.util.Comparator接口。

    如何使用

    在Java中有两个接口来支持这两个概念(Comparable和Comparator),这两个接口都有连个需要被实现的方法。分别是:
    * java.lang.Comparable: int comparaTo(Object o1)
    该方法将该对象(this)和o1进行对比,返回一个int型的值,意义如下(大小都是逻辑上的大小):
    1. positive – 该对象比o1大
    2. zero – 该对象和o1对象一样大
    3. negative – 该对象比o1对象小

    • java.util.Comparator: int compare(Object o1, Object o2)
      该方法将o1和o2进行比较,返回一个int型的值,意义如下(大小都是逻辑上的大小):

      1. positive – o1 的值比 o2大
      2. zero – o1 的值和 o2 一样大
      3. negative – o1 的值比 o2小
    • java.util.Collections.sort(List)java.util.Arrays.sort(Object [])这两个方法用把指定的list按照升序排列,这时list中的元素必须实现java.lang.Comparable接口.

    • java.util.Collections.sort(List,Comparator)java.util.Arrays.sort(Object[], Comparator)这两个方法在能够提供Comparator时对list进行排序。

    举个栗子

    考虑一个web页面需要显示职工的列表。通常情况下职工列表是按照职工的ID来排序。同样也可以根据姓名或者年龄来排序。
    我们默认的条件是员工的排序是按照职工的ID来进行排序的,下面的代码省略了各种import,不可直接粘贴代码运行

    class Employee implements Comparable<Employee> { // 职工的类
        private int id;
        private String name;
        private int age;
    
        public int compareTo(Employee e) {
            return this.getId() - e.getId();
        }
    
        public Employee(int id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public int getId(){return this.id;}
        public String getName(){return this.name;}
        public int getAge(){return this.age;}
    }

    下面我们将使用一个工具类来构造一个Employees List

    class Util {
        public static List<Employee> getEmployee() {
            List<Employee> col = new ArrayList<Employee>();
            col.add(new Employee(5, "Frank", 28));
            col.add(new Employee(1, "Jorge", 19));
            col.add(new Employee(6, "Bill", 34));
            col.add(new Employee(3, "Michel", 10));
            col.add(new Employee(7, "Simpson", 8));
            col.add(new Employee(4, "Clerk", 16));
            col.add(new Employee(8, "Lee", 40));
            col.add(new Employee(2, "Mark", 30));
    
            return col;
        }
    }

    接下来是Main方法

    public class Main {
    
        public static void main(String[] args) {
            List<Employee> coll =Util.getEmployee();
            Collections.sort(coll);
            for(Employee e: coll){
                System.out.println(e.getId() + " " + e.getName() + " " + e.getAge());
            }
        }
    }
    

    输出结果将如下所示
    1 Jorge 19
    2 Mark 30
    3 Michel 10
    4 Clerk 16
    5 Frank 28
    6 Bill 34
    7 Simpson 8
    8 Lee 40

    根据其他字段排序

    如果我们要根据employee的其他字段进行排序,上面的例子我们就要修改Employee的compareTo的实现,这样必然会破坏我们按照id进行排序的机制。其实最好的方法就是将排序策略与模型分离开来,这是Comparator就派上用场了。
    下面的代码通过构建一个内部类将coll根据Employee的name升序排列。其实只需稍微修改Main方法。

    public class Main {
    
        public static void main(String[] args) {
            List<Employee> coll =Util.getEmployee();
    
            Comparator<Employee> cmp = new Comparator<Employee>() {
                @Override
                public int compare(Employee o1, Employee o2) {
                    return o1.getName().compareTo(o2.getName());
                }
            };
    
            Collections.sort(coll, cmp);
            for(Employee e: coll){
                System.out.println(e.getId() + " " + e.getName() + " " + e.getAge());
            }
        }
    }

    输出结果如下:
    6 Bill 34
    4 Clerk 16
    5 Frank 28
    1 Jorge 19
    8 Lee 40
    2 Mark 30
    3 Michel 10
    7 Simpson 8

    同样的可以按照这种方法对id进行重排序

    其实本人是比较喜欢Comparator因为它把排序机制和数据结构分离开来了,这样代码比较容易维护。

  • 相关阅读:
    ZYNQ学习系列之GPIO
    ZYNQ7000系列学习
    新的开始
    mysql-笔记 精度
    mysql-笔记 聚合函数
    QTP自动化测试-连接数据库
    mysql create/insert
    QTP自动化测试-使用数据库-配置ODBC
    QTP自动化测试-在object repository manager中定位不到控件
    QTP自动化测试-调用函数
  • 原文地址:https://www.cnblogs.com/pluviophile/p/7460325.html
Copyright © 2020-2023  润新知