1.知识点了解

Comparator和Comparable都是用用来实现集合中元素的比较、排序的,所以,经常在集合外定义Comparator接口的方法和集合内实现Comparable接口的方法中实现排序

相同点:

二者的比较方法Comparable的compareTo和compare返回的结果有三种负数、零、正数,分别表示的关系为小于、等于、大于

不同点:

Comparator位于java.util包下,属于Collection的一员;Comparable位于java.lang包下

Comparable是一个内部比较器,实现该接口的对象相当于具有了排序的能力;Comparator是一个外部比较器,可以将两个没有实现排序的对象实现Comparator接口来实现排序,内部与外部是相对于排序代码是否在实现的排序的对象中实现的

Comparator接口中的方法如下:

java Comparator 通用 java中的comparator_数据结构与算法

Comparable中的方法如下所示:

 

java Comparator 通用 java中的comparator_java_02

建议Comparator实现java.io.Serializable接口从而序列化,因为它们经常在序列化后的TreeSet、TreeMap等数据结构中使用;equals方法经常被重写来比较引用对象是否是同一个;

2.实际应用

实现按照学生的年龄从小到大、如果年龄相等,则按照姓名的字典排序

2.1 通过Comparator外部比较器来实现排序

Student类:

 



1 public class Student {
 2     private String name;
 3     private Integer age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     Student(String name, Integer age){
11         this.name=name;
12         this.age=age;
13     }
14 
15     public Integer getAge() {
16         return age;
17     }
18 
19     public void setAge(Integer age) {
20         this.age = age;
21     }
22 
23     @Override
24     public String toString() {
25         return "Student{" +
26                 "name='" + name + '\'' +
27                 ", age=" + age +
28                 '}';
29     }

 Comparator实现排序类:

 

1 /**
 2  * 实现按照学生的年龄从小到大、如果年龄相等,则按照姓名的字典排序
 3  */
 4 public class StudentCompartor implements Comparator<Student> {
 5 
 6     @Override
 7     public int compare(Student s1, Student s2) {
 8         return (s1.getAge()-s2.getAge()==0)?(s1.getName().compareTo(s2.getName())):(s1.getAge()-s2.getAge());
 9     }
10     public static void main(String[] args){
11         StudentCompartor pc = new StudentCompartor();
12         Student p1=new Student("zhangsan",20);
13         Student p2=new Student("lisi",25);
14         Student p3=new Student("zhangsan",25);
15         if(pc.compare(p1,p2)<0){
16             System.out.println(p1);
17             System.out.println(p2);
18         }else{
19             System.out.println(p2);
20             System.out.println(p1);
21         }
22         //两者年龄相等,按照姓名排序
23         if(pc.compare(p2,p3)<0){
24             System.out.println(p2);
25             System.out.println(p3);
26         }else{
27             System.out.println(p3);
28             System.out.println(p2);
29         }
30     }
31 }

 

运行结果:

java Comparator 通用 java中的comparator_java_03

2.2通过Comparable内部比较器来实现排序

Student类:实现了Comparable接口

 

1 public class Student implements Comparable<Student> {
 2     private String name;
 3     private Integer age;
 4 
 5     public String getName() {
 6         return name;
 7     }
 8 
 9     public void setName(String name) {
10         this.name = name;
11     }
12 
13     public Integer getAge() {
14         return age;
15     }
16 
17     public void setAge(Integer age) {
18         this.age = age;
19     }
20 
21     Student(String name, Integer age) {
22         this.name = name;
23         this.age = age;
24     }
25 
26     @Override
27     public int compareTo(Student s2) {
28         return (this.getAge() - s2.getAge() == 0) ? (this.getName().compareTo(s2.getName()))
29                 : (this.getAge() - s2.getAge());
30     }
31 
32     @Override
33     public String toString() {
34         return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
35     }
36 }

内部比较器Comparable实现的排序:

 

1 /**
 2  * 实现按照学生的年龄从小到大、如果年龄相等,则按照姓名的字典排序
 3  */
 4 public class StudentComparable {
 5     public static void main(String[] args) {
 6         Student p1 = new Student("zhangsan", 20);
 7         Student p2 = new Student("lisi", 25);
 8         Student p3 = new Student("zhangsan", 25);
 9         if (p1.compareTo(p2) < 0) {
10             System.out.println(p1);
11             System.out.println(p2);
12         } else {
13             System.out.println(p2);
14             System.out.println(p1);
15         }
16         // 两者年龄相等,按照姓名排序
17         if (p2.compareTo(p3) < 0) {
18             System.out.println(p2);
19             System.out.println(p3);
20         } else {
21             System.out.println(p3);
22             System.out.println(p2);
23         }
24     }
25 }

 

运行结果同上所示。