如何对含有多个元素的数组成员进行排序?无所谓,compareTo会出手

写在前面,当这篇文章看完后,请回来再看一遍这句话,希望你会有不一样的感受!

“对含有多个元素的数组成员进行排序的关键是——解决类型转换问题”

如果一个数组中只含有整数的话,我们可使用  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));
    }
}



如果对大家有帮助,不妨点给个赞让我知道;如果有哪里需要修改,请大家在评论区不吝赐教!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值