Collection -- 01 -- Comparable和Comparator的区别

原文链接:Collection – 01 – Comparable和Comparator的区别


相关文章


在 Java 中,我们可以使用 Comparable 或者 Comparator 来实现两个元素之间比较与排序,现在让我们一起来看看它们之间有什么区别


一、Comparable

  • Comparable 是一个内部比较器,表示有能力比较的,其核心方法是 compareTo(T o)

  • 当一个类实现了 Comparable 接口时,除了要实现 compareTo(T o) 方法外,我们还要覆盖 equals(Object obj)hashCode() 方法,这是遵守了 Object.hashCode 的通用约定

    • equals() 相等的两个对象,它们的 hashCode() 也一定相等

    • hashCode() 相等的两个对象,它们的 equals() 不一定相等

  • 当我们使用 Collections.sort() 方法来对集合进行排序时,如果集合中存储的是自定义对象,则需要实现 Comparable 接口

  • 举例说明

    • Student.java

      public class Student implements Comparable<Student> {
      
          private String name;
          private Integer age;
      
          public Student(String name, Integer age) {
              this.name = name;
              this.age = age;
          }
          
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public int compareTo(@NonNull Student student) {
              // 先按照name排序
              if (this.name.compareTo(student.name) > 0) {
                  return 1;
              }
              if (this.name.compareTo(student.name) < 0) {
                  return -1;
              }
              // 再按照age排序
              if (this.age.compareTo(student.age) > 0) {
                  return 1;
              }
              if (this.age.compareTo(student.age) < 0) {
                  return -1;
              }
              return 0;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) {
                  return true;
              }
              if (o == null || getClass() != o.getClass()) {
                  return false;
              }
      
              Student student = (Student) o;
      
              if (!name.equals(student.name)) {
                  return false;
              }
              return age.equals(student.age);
          }
      
          @Override
          public int hashCode() {
              int result = name.hashCode();
              result = 31 * result + age.hashCode();
              return result;
          }
      }
      
    • ComparableTest.java

      public class ComparableTest {
      
          public static void main(String[] args) {
              TreeSet<Student> treeSet = new TreeSet<>();
              treeSet.add(new Student("Tom", 22));
              treeSet.add(new Student("Tom", 18));
              treeSet.add(new Student("Amy", 20));
              treeSet.forEach(System.out::println);
          }
      }
      
      // Student(name=Amy, age=20)
      // Student(name=Tom, age=18)
      // Student(name=Tom, age=22)
      
    • 如上所示,Student 类实现了 Comparable 接口,并实现了 compareTo() 方法中的业务逻辑,先按照学生姓名从小到大排序,再按照学生年龄从小到大排序,如果两个都相等,则视为相同对象

    • 在 main() 方法中,我们往 TreeSet 中添加了三个学生对象,排序结果如注释所示,符合预期结果


二、Comparator

  • Comparator 是一个外部比较器,表示用于比较的工具,适用于那些没有实现 Comparable 接口或者已经实现但对已有排序规则不满意的类,使用起来更加灵活,其核心方法是 compare(T o1, T o2) 接口

  • 举例说明

    • StudentComparator.java

      public class StudentComparator implements Comparator<Student> {
      
          @Override
          public int compare(Student o1, Student o2) {
              return o1.getAge() - o2.getAge();
          }
      }
      
    • ComparableTest.java

      public class ComparableTest {
      
          public static void main(String[] args) {
              TreeSet<Student> treeSet = new TreeSet<>(new StudentComparator());
              treeSet.add(new Student("Tom", 22));
              treeSet.add(new Student("Tom", 18));
              treeSet.add(new Student("Amy", 20));
              treeSet.forEach(System.out::println);
          }
      }
      
      // Student(name=Tom, age=18)
      // Student(name=Amy, age=20)
      // Student(name=Tom, age=22)
      
    • 如上所示,StudentComparator 实现了 Comparator 接口,并实现了 compare() 方法中的业务逻辑,只比较学生年龄,从小到大排序

    • 在 main() 方法中,我们往 TreeSet 的构造方法中添加了 StudentComparator,并往 TreeSet 中添加了三个学生对象,排序结果如注释所示,符合预期结果

    • 这里值得注意的,此时 Student 类本身实现了 Comparable 接口,同时比较器中实现了 Comparator 接口,当两者并存时,Comparator 的优先级要大于 Comparable


三、归纳总结

  • Comparable

    • 内部比较器,表示有能力比较的
  • Comparator

    • 外部比较器,表示用于比较的工具
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值