一文搞清楚Java中Comparable和Comparator的区别

寻技术 JAVA编程 2023年07月12日 127

Java中的ComparableComparator都是用于集合排序的接口,但它们有明显的区别。

很多人问我,到底该用哪一个,自己在使用时很疑惑?

对于这个问题,没有一定的规则来决定选择哪一个更好,因为它取决于具体情况以及开发者的个人偏好。

如果你所需要排序的类已经实现了Comparable接口,那么你可以直接使用该类默认的比较规则进行排序。否则,你可以考虑实现一个或多个Comparator接口,并基于不同的比较规则对同一个类进行排序。

在某些情况下,你可能会发现自己需要对同一个类使用多个不同的比较规则进行排序。在这种情况下,使用Comparator接口是一种更加灵活的选择,因为你可以根据需要编写任意数量的比较器,并将它们与同一个类的不同实例一起使用。

在另一些情况下,你可能会发现自然排序已经足够满足你的需求。如果你只需要对一个类中的对象按照默认的比较规则进行排序,那么你可以直接实现Comparable接口。

在本文详细介绍两者前,我申明,在Java中,ComparableComparator都是非常有用的接口,能够帮助开发者轻松地对集合进行排序,并根据特定的比较规则来确定排序顺序。具体选择哪一个接口,需要考虑多方面的因素,并且也要结合具体的需求和实际情况来进行选择。

1、Comparable

Comparable是一个排序接口,它强制实现排序规则在类本身定义,也就是说,如果一个类实现了Comparable接口,那么该类的对象就可以进行自然排序。自然排序即默认排序,如数字的升序排序、字符串的字典序排序等。

实现Comparable需要重写其中的compareTo方法,该方法的返回值类型为int,根据比较结果返回正整数、0或者负整数,其含义如下:

  • 返回正整数:当前对象大于目标对象
  • 返回0:当前对象等于目标对象
  • 返回负整数:当前对象小于目标对象

以下代码示例展示了如何实现Comparable接口:

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

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

    @Override
    public int compareTo(Person o) {
        return this.age - o.age;
    }

    // 省略getter/setter方法
}

在上述代码中,Person类实现了Comparable接口,并重写了其中的compareTo方法,按照年龄大小进行比较。这里的比较规则是年龄越小,优先级越高。

使用Comparable进行排序时,只需要对集合调用Collections.sort()方法,因为该方法已经内置了对自然排序的支持。

List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 20));
personList.add(new Person("李四", 18));
personList.add(new Person("王五", 21));
Collections.sort(personList);
System.out.println(personList);

运行上述代码,结果如下所示:

[Person{name='李四', age=18}, Person{name='张三', age=20}, Person{name='王五', age=21}]

2、Comparator

Comparator是一个比较器接口,它可以为需要排序的类提供多种不同的排序规则。与Comparable不同的是,Comparator实现的排序规则是在调用时才确定。

同样需要重写其中的compare方法,在方法中传入两个待比较的对象,并返回比较结果,含义和compareTo方法相同。但是,需要注意的是,对于同一类型的不同对象,不同的比较器实现可能会返回不同的比较结果。

以下代码示例展示了如何使用Comparator进行排序:

public class PersonAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}

List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 20));
personList.add(new Person("李四", 18));
personList.add(new Person("王五", 21));
Collections.sort(personList, new PersonAgeComparator());
System.out.println(personList);

在上述代码中,我们实现了一个PersonAgeComparator比较器,按照年龄大小进行比较。在调用Collections.sort()方法时,传入该比较器作为参数,即可按照指定的规则进行排序。

运行上述代码,结果如下所示:

[Person{name='李四', age=18}, Person{name='张三', age=20}, Person{name='王五', age=21}]

除此之外,我们还可以使用lambda表达式来简化比较器的实现:

Collections.sort(personList, (o1, o2) -> o1.getAge() - o2.getAge());

3、Comparable和Comparator的区别

  • Comparable是内部比较器,而Comparator是外部比较器。实现Comparable的类,在其内部定义了比较规则;而使用Comparator时,则需要单独定义一个外部比较器。

  • Comparable的排序规则是固定的,不可更改;而Comparator的排序规则是可以根据需要自己定义的。

  • Comparable的排序规则只适用于该类的对象,而Comparator的排序规则可以适用于不同类型的对象。

  • 当我们需要对自定义类型进行排序时,如果实现了Comparable接口,就意味着该类型具有了默认的排序规则;如果没有实现Comparable接口,则需要单独定义Comparator。

总的来说,Comparable和Comparator都是Java中用于集合排序的接口,但它们有各自的优缺点。在实际编程中,我们需要根据具体情况选择使用哪种方式,才能更加高效地完成任务。

以上就是一文搞清楚Java中Comparable和Comparator的区别的详细内容,更多关于Java Comparable和Comparator区别的资料请关注其它相关文章!

原文地址:https://juejin.cn/post/7229565416002945080
关闭

用微信“扫一扫”