Java对象要怎样才算相等?

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

一、引用相等性

    堆上同一对象的两个引用

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

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




二、对象相等性

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

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

扫描二维码关注公众号,回复: 2137353 查看本文章

就因为上面所说的内存计算问题,所以你必须覆盖过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无法猜到程序员的想法,你必须指出对象该如何排序。




猜你喜欢

转载自blog.csdn.net/swy18929564409/article/details/80745210