知识点:Comparable和Comparator接口的区别

    Comparable和Comparator都是接口,都是用来比较和排序的,那么他们两个之间到底有这什么样的区别呢?

一、Comparable用法

    在给集合排序的时候,我们需要用到一个工具类叫做Collections,这个工具类可以用来给集合排序,详见如下代码:

List<Integer> list = new ArrayList<>();
list.add(14);
list.add(30);
list.add(3);
list.add(12);
Collections.sort(list);
System.out.println(list);

    这个打印的结果是:[3,12,14,30];

    很显然,Collections对于Integer类型的数组默认的排序结果是升序的

    那么如果我们创建一个自定义类型的Person数组能否进行排序呢,大家可以用代码试一下,结果是不可以的,为什么会有这样的问题呢,我们去看一下Collections中的sort方法,就可以发现问题:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }

    在泛型的规则中,有一个T extends Comparable的泛型通配符 ,对于要排序的list中的T进行了一个限制,要求集合中的T必须要实现Comparable接口,我们可以按照这个思路,写一个Person类,实现Comparable接口,而这个接口中,有一个抽象方法需要我们实现,这个方法就是CompareTo

    

public class Person implements Comparable<Person>{
	String name;
	Integer age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {
		super();
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", 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;
	}
	//排序的规则
	public int compareTo(Person o) {
		//引用类型(可以排序的类型)可以直接调用CompareTo方法
		//基本类型--使用   减  
		//return this.age - o.age;//用this对象 - 参数中的对象,是按照该属性的升序进行的排列
		//return o.age - this.age;
		
		//return this.name.compareTo(o.name);
		//return o.name.compareTo(this.name);
		
		return this.age.compareTo(o.age);
	}

    而compareTo方法,实际上就是我们需要设置的排序的规则,到底按照什么样的方式进行排序。简单的记,使用this对象和参数比较,就是升序,反之就是降序。所以我们如果想要让Person集合中的对象按照年龄进行降序排列,就可以使用o.age -this.age;(基本类型可以使用减法替代compareTo);

    这样,你再次使用Collections.sort就可以对Person的List进行排序了,排序的结果是按照年龄的降序。

    总结一下,如果我们想要让一个List可以使用Collections.sort(list) 的方法进行排序,则必须要求集合中的元素类型,实现Comparable接口,也就是让他具备比较能力,这也是为什么Integer类型的数组可以排序,就是因为Integer已经实现了该接口,并且他是按照升序的规则实现的,这也就解释了为什么上边的第一个程序得到的结果是升序。好了那么既然Integer是按照升序的方式实现的排序,那么如果我想要得到一个降序的Integer集合该怎么办呢?难道就实现不了了么?我们接着来看下一个接口。

二、Comparator

    正如上文所说,对于已经实现了Comparable接口的集合,或者是我压根就不想实现Comparable接口的集合难道就排不了序了么,或者就无法更改排序的规则了么,实际上不是的,我们可以通过另一种方式来排序,就是利用Comparator接口。

    在集合的工具类中种还有这样的一个方法:public static <T> void sort(List<T> list, Comparator<? super T> c) 

    我们可以通过这个方法实现上面的需求:

Collections.sort(list,new Comparator<Integer>(){
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2 - o1;
			}
		});

    比如这段代码,就实现了一个Integer集合的降序排列。这个接口中有一个方法叫做compare,里边包含两个参数:如果用第一个和第二个做比较得到的就是升序,反之得到的就是降序。同样的你也可以使用这种方式对我们自己定义的类记性排序。


好了,这就是Comparable接口和Comparator接口的用法,另外要注意:

    Comparable接口位于 java.lang包下,Comparator接口位于java.util包下。

    Comparable:    内部比较器,一个类如果想要使用 Collections.sort(list) 方法进行排序,则需要实现该接口

    Comparator:    外部比较器用于对那些没有实现Comparable接口或者对已经实现的Comparable中的排序规则不满意进行排序.无需改变类的结构,更加灵活。(策略模式)


如果大家有其他疑问,可在文章下留言,如果觉得文章对自己的学习有帮助,请关注我的博客,后面会有更多的文章发布。也可以添加qq群:767375013(请备注CSDN)。里边有更多的文档视频资料,及线上免费公开课。希望和大家一起探讨。


  • 27
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值