Java对象要怎样才算相等?

如果foo与bar两对象相等,则foo.equals(bar)会返回true,且两者的hashCode()也会返回相同的值。要让Set能把对象视为重复的,就必须让它们符合上面的条件被认为是相同的。

一、引用相等性

    堆上同一对象的两个引用

 

引用到堆上同一对象的两个引用是相等的。就这样 ,如果对两个引用调用hashCode(),你会得到相同的结果。如果没有被覆盖得的话,hashCode()默认的认为会返回每个对象特有的序号。

如果想要知道两个引用是否相等,可以使用==来比较变量上的字节组合。如果引用到相同的对象,字节组合也会一样。

 

 

 

二、对象相等性

    堆上的两个不同对象在意义上是相同的

如果你想要把两个不同的Song对象视为相等的,就必须覆盖过从Object继承下来的hashCode()方法与equals()方法。

就因为上面所说的内存计算问题,所以你必须覆盖过hashCode()才能确保两个对象有相同的hashCode,也要确保以另一个对象为参数的equals()调用会返回true

==========================================================================

在一个类中重写hsahCode()方法,保证了两个对象的hashCode()值是相等的。若去掉(不重写hashCode())则两个对象的hashCode()值是不相等的。

还有,重写hsahCode()方法,保证了两个对象是相等的。反之不重写,不等。

============================================================================

HashSet如何检查重复:hashCode()与equals()

当你把对象加入HashSet时,它会使用对象的hashcode值来判断对象加入的位置。但同时也会与其他已经加入的对象的hashcode作比对,如果没有相符的hashcode,HashSet就会假设新对象没有重复出现。

也就是说,如果hashcode是相异的,则HashSet会假设对象不可能是相同的。

因此你必须override过hashCode()来确保对象有相同的值。

但是有相同的hashCode()的对象也不一定相等,所以如果HashCode找到相同的hashcode的两个对象:新加入与本来存在的,它会调用其中一个的equals()来检查hashcode相等的对象是否真的相同。

如果两者相同,HashSet就会知道要加入的项目已经重复了,所以加入的操作就不会发生。

此时不会传回异常,但add()会返回以让你判别对象是否成功的加入。因此若add()返回false,就表示新对象与集合中的某项目被认为是重复的。

总结:

(1)如果两个对象相等,则hashcode必须也是相等的

(2)如果两个对象相等,对其中一个对象调用equals()必须返回true。也就是说,若a.equals(b)则bequals(a)。

(3)如果两个对象有相同的hashcode值,他们也不一定是相等的。但若两个对象相等。则hashcode值一定是相等的。

(4)因此若equals()被覆盖过,则hashCode()也必须被覆盖。

(5)hashCode()的默认行为是对heap(堆)上的对象产生独特的值。如果你没有override过hashCode(),则该class的两个对象怎样都不会被认为是相同的。

(6)equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap(堆)上同一个对象。如果equals()没有被覆盖过,两个对象永远都不会被视为相同的,因为不同的对象有不同的字节组合。

a.equals(b)必须与a.hashCode()==b.hashCode()等值

但a.hashCode()==b.hashCode()不一定要与a.equals(b)等值。

==================================================================

如果想要保持有序,使用TreeSet

TreeSet在防止重复上面与HashSet是一样的,但它还会一直保持集合处于有序状态。

TreeSet的元素必须是Comparable,TreeSet无法猜到程序员的想法,你必须指出对象该如何排序。

 

关注公众号:工控技术之家,可留言提问相关问题,有需要可发送源代码

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值