面试题:Comparable 和 Comparator 接口有何区别?

Comparable 和 Comparator 是 Java 中用于对象排序的两个核心接口,但它们的设计目的和使用场景有所不同。以下是它们的区别:


1. 定义与用途

  • Comparable 接口
    • 定义在 java.lang 包中。
    • 用于定义对象的自然排序规则。
    • 如果一个类实现了 Comparable 接口,表示该类的对象本身具有可比较性,可以直接通过 Collections.sort() 或 Arrays.sort() 进行排序。
    • 示例:StringInteger 等类都实现了 Comparable 接口。
  • Comparator 接口
    • 定义在 java.util 包中。
    • 用于定义外部排序规则,可以在不修改类本身的情况下,为类提供多种排序方式。
    • 通常用于对未实现 Comparable 接口的类进行排序,或者需要自定义排序规则时。
    • 示例:可以通过 Comparator 实现按姓名、年龄等不同属性排序。

2. 方法

  • Comparable 接口
    • 只有一个方法:int compareTo(T o);
    • 该方法用于比较当前对象与传入对象的大小:
      • 返回负数:当前对象小于传入对象。
      • 返回零:当前对象等于传入对象。
      • 返回正数:当前对象大于传入对象。
  • Comparator 接口
    • 主要方法:int compare(T o1, T o2);
    • 该方法用于比较两个对象的大小:
      • 返回负数:o1 小于 o2
      • 返回零:o1 等于 o2
      • 返回正数:o1 大于 o2
    • 此外,Comparator 还提供了许多默认方法和静态方法(如 reversed()thenComparing() 等),用于构建复杂的排序逻辑。

3. 使用场景

  • Comparable 接口
    • 适用于类的对象有明确的自然排序规则时。
    • 例如,String 按字典序排序,Integer 按数值大小排序。
  • Comparator 接口
    • 适用于需要多种排序规则,或者无法修改类本身时。

4. 灵活性

  • Comparable 接口
    • 排序规则固定在类内部,只能有一种自然排序方式。
    • 如果需要其他排序规则,必须修改类本身。
  • Comparator 接口
    • 排序规则是外部的,可以为同一个类定义多种排序规则。
    • 更加灵活,适合需要动态调整排序规则的场景。

5. 示例代码

  • Comparable 示例
    class Student implements Comparable<Student> {
        String name;
        int score;
    
        @Override
        public int compareTo(Student other) {
            return this.score - other.score; // 按分数排序
        }
    }
    
    List<Student> students = new ArrayList<>();
    Collections.sort(students); // 使用自然排序
  • Comparator 示例
    Comparator<Student> byName = Comparator.comparing(s -> s.name); // 按姓名排序
    Comparator<Student> byScore = Comparator.comparingInt(s -> s.score); // 按分数排序
    
    List<Student> students = new ArrayList<>();
    Collections.sort(students, byName); // 使用 Comparator 排序
    Collections.sort(students, byScore.reversed()); // 按分数降序排序

总结:

特性ComparableComparator
定义位置java.lang 包java.util 包
排序规则自然排序(固定在类内部)外部排序(灵活定义)
方法compareTo(T o)compare(T o1, T o2)
使用场景类有明确的自然排序规则时需要多种排序规则或无法修改类时
灵活性较低较高
  • 如果对象的排序规则是固定的,优先使用 Comparable
  • 如果需要多种排序规则或更高的灵活性,使用 Comparator
THE END
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容