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接口。这是这两个接口的区别。