Comparable与Comparator排序

前言

对于Java对象,通常情况下只能存在==,!=的比较,而没有<或>的比较。但是实际开发中,我们却会遇到实现对象的排序,比如商品排序,按销量排序,价格排序,以及评论数排序等。可以通过java提供的两个比较器:Comparable和Comparator

Comparable接口

像String,包装类底层实现了Comparable接口,重写了compareTo(obj)方法并默认从小到大排序

  • compareTo(obj)比较规则
    如果当前对象this大于形参对象obj,则返回正整数
    如果当前对象this小于形参对象obj,则返回负整数
    如果当前对象this等于形参对象obj,则返回零
    其实实际比较的还是对象之间的字段属性值比较,在宏观角度我们把它看做是对象之间的比较罢了,伪代码如下:
@Override
public int compareTo(obj) {
	if(this.filed>obj.field){
		return 1;	
	}else if(this.filed<obj.field){
		return -1;
	}else{
		return 0;
	}

}

自定义类实现Comparable接口

同理我们也可以自定义类实现Comparable接口来对自定义类进行排序,首先,自定义一个Student类:


/**
 * 学生类
 */
public class Student  implements  Comparable<Student>{
    private int id;
    private  String name;

    public Student(int id,String name){
        this.id=id;
        this.name=name;

    }
    @Override
    public int compareTo(Student o) {
	//简写为三目运算
      return (this.id>o.id?1:(this.id==o.id?(this.name.compareTo(o.name)):-1));
    }

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

自定义Student类,并重写compareTo(),里面的方法体就是我们实现的比较逻辑,其中当id相等时,继续按照名字排序,由于String已经实现了compareTo方法,直接比较就行。OK,写完自定义类,继续来测试我们的排序方法,代码测试:

  @Test
    public void   test(){

        Student[]students=new Student[5];
        students[0]=new Student(2019,"xf");
        students[1]=new Student(2020,"aa");
        students[2]=new Student(2030,"wz");
        students[3]=new Student(2021,"zs");
        students[4]=new Student(2016,"ls");
        students[4]=new Student(2019,"af");

        Arrays.sort(students);  //实际调用compareTo()
        System.out.println(Arrays.toString(students));
        //[Student{id=2019, name='af'}, Student{id=2019, name='xf'}, Student{id=2020, name='aa'}, Student{id=2021, name='zs'}, Student{id=2030, name='wz'}]
    }

通过打印我们看到,符合我们自定义的排序规则,同时称Comparable为自然排序,我们只需重写compareTo(),就实现了排序功能。是一种在类内部就定义好的排序,我们也称Comparable为内部比较器

Comparator接口,定制排序

当元素的类型没有实现java.lang.Comparable接口而且不方便修改代码,或者实现了java.lang.Comparable接口,但是已实现的排序规则不是我们想要的,那么可以用java.util.Comparator的对象来排序,强行对多个对象整体进行排序比较,所以称Comparator为定制排序。主要重写compare(T1,T2):如果方法返回正整数,则T1>T2;如果方法返回负整数,则T1<T2:如果返回零,则T1,T2相等,注:其中的T1,T2表示泛型,继续以上面的学生类为例:

//将学生数组按照id降序排序,若id相等,按照名字降序排序
    @Test
    public void   test(){

        Student[]students=new Student[5];
        students[0]=new Student(2019,"xf");
        students[1]=new Student(2020,"aa");
        students[2]=new Student(2030,"wz");
        students[3]=new Student(2021,"zs");
        students[4]=new Student(2016,"ls");
        students[4]=new Student(2019,"af");

        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //重写排序逻辑
                return  -(s1.getId()>s2.getId()?1:(s1.getId()==s2.getId()?(s1.getName().compareTo(s2.getName())):-1));
            }
        });
        System.out.println(Arrays.toString(students));
//[Student{id=2030, name='wz'}, Student{id=2021, name='zs'}, Student{id=2020, name='aa'}, Student{id=2019, name='xf'}, Student{id=2019, name='af'}]

可以代码看出,通过Comparator对象也可以实现对象的排序,而不用去改动原有的Student类,比较灵活,所以Comparator也称为外部比较器

总结

当某个类实现Comparable接口后,就表示此类具备了排序功能,任何地方的可以直接进行排序,可以理解为此类生而就有排序功能;而Comparator是在外部动态实现类的排序,需要用到类排序就new Comparator(T)即可。所以通常把Comparable看作是内部比较器,Comparator是外部比较器。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值