快速了解Comparable和Comparator的用法与区别

最大的区别

Comparable 是通过内嵌来使用,而Comparator是通过外调来使用

在这里,内嵌和外调是我私自给予的名词,但我觉得已经能说明出他们在使用上的区别了

内嵌的Comparable
public interface Comparable<T>{
	 public int compareTo(T o);
}

Comparable实现于需要作为比较的类的内部,定义的类对Comparable进行继承,然后实现compareTo方法,强行对实现它的每个类的对象进行整体排序,但只能按类定义的某一个属性进行排序,所以也被称为自然排序。

我们通过回调的方式,利用自定义类实现compareTo的方法,可以对自定义类进行排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparableTest {

    public static class Student implements Comparable<Student>{

        private String name;
        private Integer age;

        public Student(String name,Integer age){
            this.name = name;
            this.age = age;
        }

        @Override
        public int compareTo(Student stu) {
            return this.age - stu.age;//通过年龄排序
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

    public static void main(String[] args){

        List<Student> list = new ArrayList<>();
        for(int i = 0;i < 10;i++){
            list.add(new Student("studentname" + i,20 - i));
        }
        Collections.sort(list);
        for(Student stu : list){
            System.out.println(stu);
        }
    }

}

在上述代码
list在添加时,我们是按照年龄从大到小开始添加的,但是当我们执行 Collections.sort(list); 时,改为了从小到大的排序,这是因为,在Collections在对 Student 进行排序时,调用了Student自生的compareTo方法,这样,我们就可以实现对任意一个自定义类进行比较排序,在这里是利用年龄的大小排序,也可以改写compareTo方法,实现对名字的比较进行排序,如名字的长短等,我们可以利用类自定义的任意属性,对类进行排序

外调的Comparator
public interface Comparator<T> {
	int compare(T o1, T o2);
	boolean equals(Object obj);
}

该接口有两个方法,但是对于 equals 方法我们不用去刻意实现它,因为在所有的类的父类——Object类里,已经对equals方法了,所以当我们继承Comparator时,只需要是实现它的compare方法

从Comparator 的方法参数我们就可以看出来,该接口的方法是对传入的两个参数进行比较的,所以Comparator是通过外调的方式,对传入的两个参数比较大小排序的,当某个类已经继承了Comparable且实现了它的compareTo方法,但是我们对其实现的排序方法不满意时,如String就实现了compareTo方法,但是我们又不满意该实现的方法时,我们就可以利用Comparator接口的compare方法来实现满足我们需求的排序


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorTestClass {

    public static class Student{

        private String name;
        private Integer age;

        public Student(String name,Integer age){
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }

    public static class ComparatorTest implements Comparator<Student> {

        public int compare(Student one,Student two){
            return one.getAge() - two.getAge();
        }

    }

    public static void main(String[] args){

        List<Student> list = new ArrayList<>();
        for(int i = 0;i < 10;i++){
            list.add(new Student("studentname" + i,20 - i));
        }
        ComparatorTest comparatorTest = new ComparatorTest();
        Collections.sort(list,comparatorTest);
        for(Student stu : list){
            System.out.println(stu);
        }
    }

}

在这里插入图片描述
执行结果和上述一样,我们虽然是按照年龄从大到小添加的,但是我们在ComparatorTest 类继承了Comparator接口,并实现了它的compare方法,方法里面也是按年龄大小排序,所以当我们调用 Collections.sort(list,comparatorTest); 时,Collections的内部按照我们外部调用的comparatorTest类的compare方法对list进行排序,在这里我们的Student并没有继承Comparable接口,即我们的Student类不支持自定义的排序,这个时候,我们就可以用过外调某一个类,该类一定继承了Comparator且实现了它的方法,这时,我们使然没有在Student内部定义排序方式但是我们仍然可以通过外调的方式进行排序,所以我们说Comparator时一种外调的方式

当一个类没有排序方法,或者不满意某一个类内部继承Comparable而实现的排序,我们又对该源码无法更改时,就可以通过这种方式进行自定义的继承Comparator实现compare,进行重定义排序

总结

Collections.sort();这个方法,当我们只传入一个参数时,该方法会检测参数的参数是否是继承了Comparable类实现了它的方法,因为这种排序方式,是通用回调的方式调用参数内部的Comparable的compareTo方法对参数进行排序的,放该参数没有继承该Comparable接口而,又通过Collections.sort(Student);的方式排序时,就会报错,这个时候,我们就可以利用第二种方式
——Collections.sort(list,comparatorTest);进行排序,凡是第二个参数一定是继承了Comparator接口实现了compare方法的,实例化对象,这样才能进行排序,简单而言就是,第一中方式相当于是Comparable接口的类内嵌式比较排序,第二种是Comparator接口的外调式排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值