【java】比较器的使用

比较器的使用

  • 比较器的实质就是重载比较运算符
  • 比较器可以很好地应用在特殊标准的排序上
  • 比较器可以很好地应用在根据特殊标准排序的结构上

Comparable VS Comparator

Comparable 和 Comparator 都是接口,用来对自定义的类进行比较。

区别:

  • Comparable 是定义在自定义类的内部,需要自定义类实现 compareTo 方法。例如 String 类就实现了 Comparable 接口,所以 Arrays.sort(String)、Collections.sort(String) 等方法才能获得正确的结果。

  • Comparator 是定义在自定义类的外部,自定义类结构不需要有任何变化,我们自定义一个比较器,实现 compare 方法

    public class XXXComparator implements Comparator<XXX> {
        @Override
        public int compare(XXX o1, XXX o2) {
          ……   //实现比较自定义
        }
    }
    //使用: Arrays.sort(XXX数组,new XXXComparator);
    

总结:实现 Comparable 接口的对象可以直接作为比较的对象,但是需要修改自定义类的结构。用Comparator 的好处是不需要修改自定义类的结构,并且可以根据实际需要实现比较器而不用在自定义类时就思考如何比较。

举例

public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Student o) {
        //将学生按年龄递增排序,年龄相同姓名递减排序
        if (this.age == o.age) {
            //String类实现了Comparable接口
            return o.name.compareTo(this.name);
        }
        return this.age - o.age;
    }

    @Override
    public String toString() {
        return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
    }

    public static void main(String[] args) {
        Student[] students = {
            new Student("A", 15),
            new Student("B", 14),
            new Student("C", 13),
            new Student("D", 15),
            new Student("E", 13),
            new Student("F", 10),
            new Student("G", 11),
            new Student("H", 15)
        };
        //将学生按年龄递增排序,年龄相同姓名递减排序
        //方法一 使用Comparable接口
        Arrays.sort(students);
        //方法二 使用Comparator
//        Arrays.sort(students, new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                if (o1.age == o2.age) {
//                    return o2.name.compareTo(o1.name);
//                } else {
//                    return o1.age - o2.age;
//                }
//            }
//        });
        
        for (Student student : students) {
            System.out.println(student.toString());;
        }
    }
}

【注】

无论是 Comparable 接口的A.compareTo(B) 方法 还是 Comparator 的compare(A,B) 方法。返回的 int 值 无非是负数、0、正数。

而 Arrays.sort 之类的方法进行排序遵守的原则是:

  • 当返回负数时,A排在B前面
  • 当返回正数时,A排在B后面
  • 当返回0的时候,相对顺序不变

举例:

public class AgeAscComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}

在这个比较器里,当返回负数时,o1的年龄比o2小,o1排在o2 前;返回正数时,o1的年龄比o2大,o1排在o2后;返回零两人年龄相等,位置不变。也就是说排完序后,排在前面的学生年龄比排在后面的学生年龄小,很明显是实现按年龄升序排序的比较器。

若想改造成按年龄降序排序的比较器,只需简单修改就可,如下

public class AgeDescComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {
        return o2.age - o1.age;
    }
}

在这个比较器里,当返回负数时,o1的年龄比o2大,o1排在o2 前;返回正数时,o1的年龄比o2小,o1排在o2后;返回零两人年龄相等,位置不变。也就是说排完序后,排在前面的学生年龄比排在后面的学生年龄大,很明显是实现按年龄降序排序的比较器。

posted @   hzyuan  阅读(343)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)

喜欢请打赏

扫描二维码打赏

支付宝打赏

点击右上角即可分享
微信分享提示