写在前面,当这篇文章看完后,请回来再看一遍这句话,希望你会有不一样的感受!
“对含有多个元素的数组成员进行排序的关键是——解决类型转换问题”
如果一个数组中只含有整数的话,我们可使用 Arrays.sort(数组名) 来对数组进行排序,如下:
public class Test {
public static void main(String[] args) {
int[] array = new int[]{4,2,7};
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}
但是,如果数组中的成员含有多个元素怎么办呢?
import java.util.Arrays;
class Student{
public String name;
public int age;
public int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
public class Test {
public static void main(String[] args) {//对这个数组排序怎么排?
Student[] students = new Student[3];
students[0] = new Student("zhangsan", 19, 10);
students[1] = new Student("lisi", 24, 59);
students[2] = new Student("wangwu", 30, 69);
Arrays.sort(students);
System.out.println(Arrays.toString(students));
}
}
如上述代码所示:student数组含有三个成员,每个成员含有三个元素。此时编译器会不知道根据什么来排序?姓名?年龄?成绩?结果会报错
这里表示:将数组“a”的一个成员转型为“Comparable”类型后,调用其中的“compareTo”方法。
对应编译器的异常报告:ClassCastException,说明在这里发生了类型转换异常
我们再点击“Comparable”类型,进行详细查看
发现这是一个接口,里面有一个“compareTo”方法
也就是说,我们要把我们数组中的成员“student”转换成这个“Comparable”类型。所以我们给Student类加上Compapable接口,并重写其中的方法
根据下图可知,我们是通过comparableTo方法来比较大小的,而这个方法的返回值为整数,所以我们可以根据返回值来判断比较结果
那么现在,假设我们要以年龄为比较对象对Student数组中的元素进行排序,那么comparableTo方法该怎么写呢? (大于返回1,小于返回-1,相等返回0)
@Override
public int compareTo(Student o) {
if (this.age > o.age){
return 1;
}else if(this.age < o.age){
return -1;
}else {
return 0;
}
}
那么现在,假设我们要以姓名(字符串类型)为比较对象对Student数组中的元素进行排序,那么comparableTo方法该怎么写呢?
我们将同样使用String类中的comparableTo方法来对两个字符串进行比较。比较方法是一个字母一个字母比较顺序
@Override
public int compareTo(Student o) {
if (this.name.compareTo(o.name)>0){//注意!这里的comparableTo是String类中的!!!
return 1;
}else if(this.name.compareTo(o.name)<0){
return -1;
}else {
return 0;
}
}
那么现在,我们已经处理了开头我们所说的“类型转换异常”。看一看这个代码的全貌并运行一下
import java.util.Arrays;
class Student implements Comparable<Student>{
public String name;
public int age;
public int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
/*@Override
public int compareTo(Student o) {
if (this.age > o.age){
return 1;
}else if(this.age < o.age){
return -1;
}else {
return 0;
}
}*/
@Override
public int compareTo(Student o) {
if (this.name.compareTo(o.name)>0){//注意!这里的comparableTo是String类中的!!!
return 1;
}else if(this.name.compareTo(o.name)<0){
return -1;
}else {
return 0;
}
}
}
public class Test {
public static void main(String[] args) {//对这个数组排序怎么排?
Student[] students = new Student[3];
students[0] = new Student("zhangsan", 19, 10);
students[1] = new Student("lisi", 24, 59);
students[2] = new Student("wangwu", 30, 69);
Arrays.sort(students);
System.out.println(Arrays.toString(students));
}
}
其实到目前为止,这个“类型转换错误“的问题我们已经解决了。但是这样写起来调用很麻烦,如果想换一种比较方式就要修改代码,风险很大。那么为什么我们不能使用接口让其更加灵活呢?
写一个用年龄为比较方式的类来实现一个Comparator的接口,这个接口中有一个compare的方法
class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
仍然是根据返回值的正负来判断大小(只管判断大小,剩下的sort会出手!目前可以简单地把sort方法看作是一个类似于冒泡排序的东西)
现在我们写了一个实现了接口且按照年龄排序的类,那么我们如何使用呢?
在Arrays类中,存在许多sort方法,其中一个sort方法允许我们传一个Comparator的参数
public class Test {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("zhangsan", 19, 10);
students[1] = new Student("lisi", 24, 59);
students[2] = new Student("wangwu", 30, 69);
AgeComparator ageComparator = new AgeComparator();//比较器
Arrays.sort(students,ageComparator);
System.out.println(Arrays.toString(students));
}
}
我们以此类推,可以写出以姓名或者成绩为比较方式的比较器,代码如下
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
class Student{
public String name;
public int age;
public int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
class ScoreComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.score - o2.score;//减数交换改变排列顺序
}
}
class NameComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
}
public class Test {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("zhangsan", 19, 10);
students[1] = new Student("lisi", 24, 59);
students[2] = new Student("wangwu", 30, 69);
// AgeComparator ageComparator = new AgeComparator();//比较器
// ScoreComparator scoreComparator = new ScoreComparator();
NameComparator nameComparator = new NameComparator();
// Arrays.sort(students,ageComparator);
// Arrays.sort(students,scoreComparator);
Arrays.sort(students,nameComparator);
System.out.println(Arrays.toString(students));
}
}
如果对大家有帮助,不妨点给个赞让我知道;如果有哪里需要修改,请大家在评论区不吝赐教!