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 }

测试结果:

原文地址:https://www.cnblogs.com/wk-missQ1/p/12768573.html