• Java基础知识之Comparable和Comparator接口的区别


     Comparable接口和Comparator接口的用法:

      Comparable接口位于 java.lang包下,Comparator接口位于java.util包下。

      Comparable:    内部比较器,一个类如果想要使用 Collections.sort(list) 方法进行排序,则需要实现该接口

      Comparator:    外部比较器用于对那些没有实现Comparable接口或者对已经实现的Comparable中的排序规则不满意进行排序.无需改变类的结构,更加灵活。

    两种比较器Comparable和Comparator,后者相比前者有如下优点:

      1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法

      2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式

    Comparable:

      Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法

     1 public class Student implements Comparable<Student>{
     2     private String name;
     3     private Integer age;
     4     private int stuNo;
     5 
     6     public Student(String name,Integer age,int stuNo){
     7         this.name = name;
     8         this.age = age;
     9         this.stuNo = stuNo;
    10     }
    11     public String getName() {
    12         return name;
    13     }
    14 
    15     public void setName(String name) {
    16         this.name = name;
    17     }
    18 
    19     public Integer getAge() {
    20         return age;
    21     }
    22 
    23     public void setAge(Integer age) {
    24         this.age = age;
    25     }
    26 
    27     public int getStuNo() {
    28         return stuNo;
    29     }
    30 
    31     public void setStuNo(int stuNo) {
    32         this.stuNo = stuNo;
    33     }
    34 
    35     //和自己比较
    36     @Override
    37     public int compareTo(Student o) {
    38         return this.stuNo - o.getStuNo();
    39     }
    40 }

    测试类:

    1 public class Test3 {
    2     public static void main(String[] args) {
    3         Student s1 = new Student("ming",8,1);
    4         Student s2 = new Student("tian",9,2);
    5         //通过s1 和 s2 的stuNo进行比较
    6         System.out.println("s1的stuNo-s2的stuNo:"+s1.compareTo(s2));
    7     }
    8 }

    测试结果:

       实现Comparable接口的类是可以支持和自己比较的,但是其实代码里面Comparable的泛型可以指定为String或者为其他任何任何类型都可以----只要开发者指定了具体的比较算法就行。

     1 public class Person {
     2     private String name;
     3     private Integer age;
     4 
     5     public Person(String name,Integer age){
     6         this.name = name;
     7         this.age = age;
     8     }
     9     public String getName() {
    10         return name;
    11     }
    12 
    13     public void setName(String name) {
    14         this.name = name;
    15     }
    16 
    17     public Integer getAge() {
    18         return age;
    19     }
    20 
    21     public void setAge(Integer age) {
    22         this.age = age;
    23     }
    24 }

    泛型为Person类型:

     1 public class PersonComparable implements Comparable<Person> {
     2     private String name;
     3     private int age;
     4 
     5     public PersonComparable(String name, int age){
     6         this.age = age;
     7         this.name = name;
     8     }
     9 
    10 
    11     //排序规则,自己实现排序逻辑
    12     @Override
    13     public int compareTo(Person o) {
    14         //使用age进行排序
    15         return this.age - o.getAge();
    16     }
    17 }

    测试类:

     1 public class Test1 {
     2     public static void main(String[] args) {
     3         PersonComparable p1 = new PersonComparable("xiaoming",3);
     4         Person p11 = new Person("xiaom",5);
     5         PersonComparable p2 = new PersonComparable("xiaoliang",5);
     6         Person p22 = new Person("xiaol",4);
     7         System.out.println("p1和p11的age比较:"+p1.compareTo(p11));
     8         System.out.println("p2和p22的age比较:"+p2.compareTo(p22));
     9     }
    10 }

    测试结果:

     Comparator:

      Comparator可以认为是是一个外比较器,个人认为有两种情况可以使用实现Comparator接口的方式:

      1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较

      2、一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式

      Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int.

    1 public class PersonComparator implements Comparator<Person> {
    2     //排序算法,自己实现排序逻辑
    3     @Override
    4     public int compare(Person o1, Person o2) {
    5         //因为Person对象的age属性使Integer类型的,Integer实现了Comparable接口,实现了compareTo方法
    6         return o1.getAge().compareTo(o2.getAge());
    7     }
    8 }

    测试类:

     1 public class Test2 {
     2     public static void main(String[] args) {
     3         PersonComparator personComparator = new PersonComparator();
     4         Person p1 = new Person("xiaomi",10);
     5         Person p2 = new Person("xiaowei",30);
     6         // 因为使用的是Integer默认实现,所以
     7         // 如果结果>0,表示p1.get>p2.age;
     8         // 如果结果=0,表示p1.age = p2.age;
     9         // 如果结果<0,表示p1.age < p2.age;
    10         System.out.println("p1和p2比较结果:"+personComparator.compare(p1, p2));
    11     }
    12 }

    测试结果:

  • 相关阅读:
    fabric.js 学习
    前端基础回顾
    ubuntu16 mysql 远程连接
    Django rest_framework API 随笔
    django 学习笔记
    vue 返回上一页在原来的位置
    Django mysql 改用pymysql 驱动
    Material-UI
    设置placeholder的样式
    Cookie、session和localStorage、以及sessionStorage之间的区别
  • 原文地址:https://www.cnblogs.com/wk-missQ1/p/12768573.html
Copyright © 2020-2023  润新知