Comparator 和 Comparable的使用及区别

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 比较器实战应用)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值