在Java语言中,Comparable和Comparator都是用来对元素进行排序的,但是它们有着本质的区别。这两个也是常见的面试题,所以今天我们就一起来探讨一下。1、字面意思不同。我们从两者的字面意思来理解。Comparable翻译成中文是“比较”,而Comparator是“比较器”的意思。Comparable以-able结尾,表示它具有一定的能力,而Comparator以-or结尾,表示它是比较的参与者。这是从字面意思上看两者的区别。2.用法不同。两者都是顶层接口,但是方法和用法不同。下面我们分别来看一下。2.1ComparableComparable接口只有一个compareTo方法,实现Comparable接口重写compareTo方法可以实现对某个类的排序,支持Collections.sort和Arrays.sort排序。当我们不使用Comparable时,程序的执行是这样的:{//创建对象Personp1=newPerson(1,18,"Java");Personp2=newPerson(2,22,"MySQL");Personp3=newPerson(3,6,"Redis");//加入集合Listlist=newArrayList<>();list.add(p1);list.add(p2);list.add(p3);//打印集合信息list.forEach(p->System.out.println(p.getName()+":"+p.getAge()));}}//下面的set/get/toString都是使用lombok提供的注解@Getter@Setter@ToStringclassPerson{privateintid;privateintage;privateStringname;publicPerson(intid,intage,Stringname){this.id=id;this.age=age;this.name=name;}}程序执行结果如下:从上图可以看出,当自定义类Person没有实现Comparable,List集合是没有排序的,只有插入顺序元素的数量可以用作输出顺序。但是,这时候老板有个要求:按照Person对象的age属性倒序,即按照age属性从大到小排序。这个时候,请出来。我们文章的主角:可比来了。Comparable的使用是在自定义对象的类中实现Comparable接口,重写compareTo方法实现自定义排序规则。具体实现代码如下:importlombok.Getter;importlombok.Setter;importlombok.ToString;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;publicclassComparableExample{publicstaticvoidmain(String[]args){//创建对象Personp1=newPerson(1,18,"Java");Personp2=newPerson(2,22,"MySQL");Personp3=newPerson(3,6,"Redis");//添加对象到集合中Listlist=newArrayList<>();list.add(p1);list.add(p2);清单。add(p3);//排序操作(按照Person类中compareTo定义的排序规则)Collections.sort(list);//输出集合中的顺序list.forEach(p->System.out.println(p.getName()+":"+p.getAge()));}}//下面的set/get/toString都是使用lombok提供的@Getter@Setter@ToStringstaticclassPersonimplementsComparable{privateintid;privateintage;privateStringname;publicPerson(intid,intage,Stringname){this.id=id;this.age=age;this.name=name;}@OverridepublicintcompareTo(Personp){returnp.getAge()-this.getAge();}}程序执行结果如下图所示:compareTo排序方法说明compareTo方法接收的参数p为待比较对象,排序规则为当前对象与待比较对象进行比较,然后返??回一个int类型的值positive从小到大的排序规则是:用当前对象值减去被比较对象的值;而从大到小的反向排序规则正好相反:用被比较对象的值减去当前对象的值。注意:如果自定义对象没有实现Comparable接口,则无法使用Collections.sort方法进行排序,编译器会提示如下错误:图2.2ComparatorComparator和Comparable的排序方式不同,排序方式Comparable的是compareTo,Comparator的排序方式是compare,具体实现代码如下:importlombok.Getter;importlombok.Setter;importjava.util.ArrayList;导入java.util.集合;importjava.util.Comparator;importjava.util.List;String[]args){//创建对象Personp1=newPerson(1,18,"Java");Personp2=newPerson(2,22,"MySQL");Personp3=newPerson(3,6,"Redis");//添加对象到集合Listlist=newArrayList<>();list.add(p1);list.add(p2);list.add(p3);//排序操作(按照定义的排序PersonComparatorRules)Collections.sort(list,newPersonComparator());//输出集合中的顺序list.forEach(p->System.out.println(p.getName()+":"+p.getAge()));}}/***Person类的比较器*/classPersonComparatorimplementsComparator{@Overridepublicintcompare(Personp1,Personp2){returnp2.getAge()-p1.getAge();}}@Getter@SetterclassPerson{privateintid;privateintage;privateStringname;publicPerson(intid,intage,Stringname){this.id=id;this.age=age;}}程序执行结果如下图所示:Extension:Comparator匿名类Comparatorcanbecreatedby除了自定义比较器,还可以使用匿名类来更快捷方便地完成自定义比较器的功能。具体代码实现如下:importlombok.Getter;importlombok.Setter;importjava.util.ArrayList;importjava.util.Comparator;importjava.util.List;publicclassComparatorExample{publicstaticvoidmain(String[]args){//构建并添加数据Listlist=newArrayList<>();list.add(newPerson(1,18,"Java"));list.add(newPerson(2,20,"MySQL"));list.add(newPerson(3,6,"Redis"));//使用Comparator匿名类排序list.sort(newComparator(){@Overridepublicintcompare(Personp1,Personp2){returnp2.getAge()-p1.getAge();}});//打印采集数据list.forEach(p->System.out.println(p.getName()+":"+p.getAge()));}}@Getter@SetterstaticclassPerson{privateintid;privateintage;privateStringname;publicPerson(intid,intage,Stringname){this.id=id;this.age=age;这个.name=name;}}程序的执行结果如下图所示:3.使用的场景不同从上面例子的实现代码可以看出,原来的类必须修改为使用Comparable,即是,您要排序的类。需要实现Comparable接口,重写其中的compareTo方法,所以Comparable更像是一个“内部”排序的接口,而Comparator的使用则不同,Comparator不需要修改原来的类。也就是说,在最极端的情况下,即使Person类是第三方提供的,我们仍然可以通过新建自定义比较器Comparator来对第三方类Person进行排序。也就是说,可以通过Comparator接口实现与原类的解耦,不用修改原类就可以实现排序功能,所以Comparator可以看作是一个“对外”提供排序的接口。总结一下,Comparable和Comparator都是用来对元素进行排序的。它们的区别如下:Comparable是“比较”的意思,而Comparator是“比较器”的意思;Comparable是通过重写compareTo方法实现排序,Comparator是通过重写compare方法实现排序;Comparable必须由自定义类在内部实现排序方法,而Comparator是在外部定义并实现排序的。所以一句话概括两者的区别:Comparable可以看作是“内部”排序的接口,而Comparator是“外部”排序的接口。判断是非在自己,名誉在别人,得失在人数。博主介绍:80后程序员,“坚持”写博客12年。爱好:阅读、慢跑和羽毛球。本文转载自微信公众号《Java面试题解析》,可通过以下二维码关注。转载本文请联系Java面试真题解析公众号。