TreeSet自定义类型的排序 Comparable 和 Comparator

需要给自定义类型实现比较接口
实现了比较接口以后,不需要再写equals了,因为comapreTo已经帮忙比较的事情,如果两个对象相等,compareTo的结果是0,新的值会覆盖旧的值
在这里插入图片描述
到 add(p2)的时候
会报错说
ClassCastException: Person cannot be cast to class java.lang.Comparable

因为TreeSet调用add方法,其实是底层调用了 TreeMap 的 put方法

new TreeSet<>() new 的时候,调用的是无参构造方法
在这里插入图片描述
在TreeMap里面的无参构造方法中,会给compatator赋一个null
在这里插入图片描述
在TreeMap的put方法中,如果看到comparator是空,会把key强转成 Comparable 类型
在这里插入图片描述
而Person类型不是Comparable, Person类没有实现java.lang.Comparable接口

Comparator 和 Comparable

java.util.Comparator
comparator.compare(o1, o2)

java.lang.Comparable
o1.compareTo(o2)

两者怎么选择呢?
如果比较规则经常变化,可以写多个比较器,符合OCP原则
当比较规则只有一个不变化的时候,建议实现Comparable接口

这两者是有区别的

方法一:为自定义类实现Comparable接口

如果要改,改成下面这样:实现Comparable接口

class Customer implements Comparable<Customer>{
	int age;
	public Customer(int age);
	@Override
	public int compareTo(Customer c){
		return this.age - c.age; //这样默认是升序
		// return c.age - this.age; //这样是降序
	}
}

另外, TreeSet / TreeMap 集合采用的是:中序遍历方式:左根右

方法二 单独编写比较器

自己创建一个比较器,然后在构造TreeSet的时候,把构造器传到构造函数里面

在这里插入图片描述
在这里插入图片描述

class MyComparator implements Comparator<MyPet>{
	@Override
	默认是升序,反过来就是降序
	public int compare(MyPet o1, MyPet o2){
		return o1.age - o2.age;
	}
}

然后把比较器传给TreeSet

TreeSet<MyPet> pets = new TreeSet<MyPet>(new MyComparator());

或者用匿名内部类的方式,直接new接口,后面加大括号

TreeSet<MyPet> pets = new TreeSet<MyPet>(new Comparator<MyPet>(){
	@Override
	public int compare(MyPet o1, MyPet o2){
		return o1.age - o2.age;
	}
}

如果要对List集合中的元素排序,也是一个道理:要对集合中的元素实现 Comparable 接口

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值