Comparable比较器和Comparator比较器

1、Comparable比较器

Arrays类中存在sort()排序方法,此方法可以直接对对象数组进行排序。

1 public static void sort(Object[] a

根据元素的自然顺序对指定对象数组按升序进行排序。但前提是数组中的所有元素都必须实现 Comparable 接口,并覆写compareTo()方法指定对象排序的规则。

Comparable接口定义于java.lang包中:public interface Comparable<T>;int compareTo(T t)方法比较此对象与指定对象的顺序。

现在新建一个Student类,实现按照成绩的由高到低排序:

 1 import java.util.Arrays;
 2 
 3 class Student implements Comparable<Student> { //指定比较的类型也是Student
 4     private String name;
 5     private float score;
 6     public Student(String name,float score){
 7         this.name = name;
 8         this.score = score;
 9     }
10     public String toString(){
11         return "姓名: " + this.name + "\t"+"成绩: "+this.score;
12     }
13     @Override
14     public int compareTo(Student o) {
15         if(this.score>o.score)
16             return 1;
17         if(this.score<o.score)
18             return -1;
19         return 0;
20     }
21 }
22 
23 public class TestComparable {
24     public static void main(String args[]){
25         Student stus[] = {new Student("夏小宝",99.0f),
26                 new Student("李花花",100.0f),new Student("陆小凤",90.0f),
27                 new Student("李寻欢",88.5f)};
28         Arrays.sort(stus);
29         for (int i = 0; i < stus.length; i++) {
30             System.out.println(stus[i]);
31         }
32     }
33 }

 

若是Student类没有实现Comparable接口,则在使用Arrays.sort()方法时程序会出现 java.lang.ClassCastException异常。

2、Comparator比较器

如果一个类已经开发完成,但是在此类建立的初期并没有实现Comparable接口,此时肯定无法进行对象排序操作,所以为了解决这样的问题,Java又定义了另一个比较器的操作接口--Comparator接口。

1 public interface Comparator<T>
2 int compare(T o1, T o2) //比较用来排序的两个参数
3 boolean equals(Object obj) //指示某个其他对象是否“等于”此 Comparator

 

新建一个学生类,要求按照成绩的由高到低进行排序。但在这个学生类中我们按照常规的定义,只是在其中覆写了Object类中的equals方法,不再实现Comparable接口。

 1 class Student{
 2     private String name;
 3     private float score;
 4     public Student(String name,float score){
 5         this.name = name;
 6         this.score = score;
 7     }
 8     public String getName() {
 9         return name;
10     }
11 
12     public void setName(String name) {
13         this.name = name;
14     }
15 
16     public float getScore() {
17         return score;
18     }
19 
20     public void setScore(float score) {
21         this.score = score;
22     }
23 
24     public String toString(){
25         return "姓名: " + this.name + "\t"+"成绩: "+this.score;
26     }
27     public boolean equals(Object o){  //覆写Object类中的equals方法
28         if(this == o){
29             return true;
30         }
31         if(!(o instanceof Student)){
32             return false;
33         }
34         Student stu = (Student)o;  //对Object类向下转型
35         if(this.name.equals(stu.name)&&this.score == stu.score){
36             return true;
37         }else{
38             return false;
39         }
40     }
41 }

 

当然这样的类是不能进行对象排序的,为了让此类可以进行排序操作,所以需要单独为此类定义一个比较器,此比较器实现Comparator接口。应该注意的是这时调用sort方法时应该调用他的重载方法:

public static <T> void sort(T[] a,
                            Comparator<? super T> c)

 

 1 import java.util.Arrays;
 2 import java.util.Comparator;
 3 
 4 class StudentComparator implements Comparator<Student>{ //实现Comparator接口,指定比较类型为Student
 5     //Comparator接口存在compare和equals两个方法,但StudentComparator类中已经从Object类中继承了equals方法,不需要在覆写
 6     @Override
 7     public int compare(Student arg0, Student arg1) {
 8         if(arg0.getScore() == arg1.getScore()){
 9             return 0;
10         }
11         if(arg0.getScore() > arg1.getScore()){
12             return 1;
13         }else{
14             return -1;
15         }
16     }
17 }
18 
19 public class TestComparator {
20     public static void main(String args[]){
21         Student stus[] = {new Student("夏小宝",99.0f),
22                 new Student("李花花",100.0f),new Student("陆小凤",90.0f),
23                 new Student("李寻欢",88.5f)};
24         Arrays.sort(stus,new StudentComparator());
25         for (int i = 0; i < stus.length; i++) {
26             System.out.println(stus[i]);
27         }
28     }
29 }

 

可以看到,Comparable比较器是在需要比较的类在定义时就要实现。而如果一个类已经定义好,但我们又不想修改类的定义或修改起来比较麻烦,我们就为此类单独定义一个比较器,这个比较器实现Comparator接口。这是这两个接口的区别。

 

posted @ 2018-01-15 14:46  weller  阅读(269)  评论(0编辑  收藏  举报