Comparable的使用
1.1、我们创建一个Student(学生)类
class Student {
public int age;
public String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "{" + "age=" + age +
", name='" + name + "}";
}
}
1.2、我们来进行测试
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student(22,"LeeSin");
students[1] = new Student(26,"Ashy");
students[2] = new Student(24,"Timor");
Arrays.sort(students);
//Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable
System.out.println(Arrays.toString(students));
}
}
此时会发生运行时异常:
java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable
这个意思就是类型转换异常。
因为自定义类型不能转换为sort原来方法中排序的类型,所以我们需要写一个比较器。
1.3、Class Student实现Comparable接口
class Student implements Comparable<Student>{
public int age;
public String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "{" + "age=" + age +
", name='" + name + "}";
}
//通过年龄比较
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
this.age - o.age 表示当前age-传入的age,结果是升序;
如果是o.age - this.age 那么表示的是降序;
1.4我们再来测试
public class Test {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student(22,"LeeSin");
students[1] = new Student(26,"Ashy");
students[2] = new Student(24,"Timor");
Arrays.sort(students);
System.out.println(Arrays.toString(students));
//[{age=22, name='LeeSin}, {age=24, name='Timor}, {age=26, name='Ashy}]
}
}
结果是[{age=22, name='LeeSin}, {age=24, name='Timor}, {age=26, name='Ashy}],我们发现数组通过年龄升序排序
1.5、同样的,我们也可以通过姓名首字母来比较
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student(22,"LeeSin");
students[1] = new Student(26,"Ashy");
students[2] = new Student(24,"Timor");
Arrays.sort(students);
System.out.println(Arrays.toString(students));
//[{age=26, name='Ashy}, {age=22, name='LeeSin}, {age=24, name='Timor}]
}
}
class Student implements Comparable<Student>{
public int age;
public String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "{" + "age=" + age +
", name='" + name + "}";
}
@Override
public int compareTo(Student o) {
return this.name.compareTo(o.name);
}
/*@Override
public int compareTo(Student o) {
return this.age - o.age;
}*/
}
结果是[{age=26, name='Ashy}, {age=22, name='LeeSin}, {age=24, name='Timor}],我们发现数组是以name首字母来排序的。
Comparator比较器
1.1我们继续使用上面的Student(学生)类
import java.util.Arrays;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student(22,"LeeSin");
students[1] = new Student(26,"Ashy");
students[2] = new Student(24,"Timor");
//根据首字母排序
NameComparator nameComparator = new NameComparator();
Arrays.sort(students,nameComparator);
System.out.println(Arrays.toString(students));
//[{姓名=Ashy,年龄=26 }, {姓名=LeeSin,年龄=22 }, {姓名=Timor,年龄=24 }]
//根据年龄排序
AgeComparator ageComparator = new AgeComparator();
Arrays.sort(students,ageComparator);
System.out.println(Arrays.toString(students));
//[{姓名=LeeSin,年龄=22 }, {姓名=Timor,年龄=24 }, {姓名=Ashy,年龄=26 }]
}
}
class Student {
public int age;
public String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "{" + "姓名=" + name + ",年龄=" + age + " " + "}";
}
}
class AgeComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
}
结果分别是是:
[{姓名=Ashy,年龄=26 }, {姓名=LeeSin,年龄=22 }, {姓名=Timor,年龄=24 }]
[{姓名=LeeSin,年龄=22 }, {姓名=Timor,年龄=24 }, {姓名=Ashy,年龄=26 }]
Comparator和Comparable的区别
细心的同学会发现我们使用Comparable接口用name首字母比较时,
先屏蔽了重写的age比较方法。
@Override
public int compareTo(Student o) {
return this.name.compareTo(o.name);
}
/*@Override
public int compareTo(Student o) {
return this.age - o.age;
}*/
因为一个类里面重写的compareTo方法只有一个,当我们选择用name首字母比较后,就不能用age大小来比较,这就是Comparable的局限性,一旦写死,只能用一种方法比较。但是我们使用Comparator比较器的时候,既可以用name比较,也可以用age比较。
当然,Comparator也可以像Comparable一样用来实现:
class Student implements Comparator<Student>{
public int age;
public String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "{" + "姓名=" + name + ",年龄=" + age + " " + "}";
}
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
效果是一样的。
还有一点就是Comparable重写的是compareTo方法;
来看下Comparable源码:
public int compareTo(T o);
只有一个需要重写的方法。
而Comparator重写的是compare方法,但是它却又很多方法。
老规矩,小白入门,如有错误,请多多包含指正。
谢谢!
另外,我另外一篇博客写了< > == 和equals的使用,链接如下,欢迎来访!!!
java中的比较== < > Comparator和 Comparable
还有一篇刷题中使用比较器的博客
字符统计与查找 和 最小的 k 最数字(Comparator 比较器实战应用)