hashCode()和equals()之对象对比

hashCode()和equals()之对象对比

参考以下两文
https://mp.weixin.qq.com/s?__biz=MzIyNDU2ODA4OQ==&mid=2247483944&idx=1&sn=3a81af53aaaac56b60e50c1619433513&chksm=e80db45edf7a3d48807151107efd8d2b39f04424b6b1fe57212a92ea2b4927702a5250c37fa7&scene=21#wechat_redirect

https://www.cnblogs.com/keyi/articles/7119825.html

杂谈:

当equals方法被重写时,通常有必要重写hashCode方法,以维护hashCode方法的常规约定:值相同的对象必须有相同的hashCode;

hashCode默认是由内存地址计算的;

equals默认比较对象内存地址,即使两个属性值相同的对象内存地址也一定不同(两个对象的内存地址一定不同);

因为重写的equal()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高,那么hashCode()既然效率这么高为什么还要equal()呢?

HashCode相等,equals不一定为True (HashCode算法公式问题(哈希碰撞?),极小概率不同对象会得到一样的hashCode),所以默认的hashCode不绝对可靠

重写规矩:

equals() 通常进行同类对象的属性比较;

equals() True,hashCode必须相等;

equals() False, hashCode必须不相等;

如果只重写了equals方法,而不重写hashcode的方法,会造成hashcode的值不同(内存地址不一样)但equals()方法判断出来的结果为true,这样不利于我们比较属性值一样的两个对象。

@Override
 public boolean equals(Object o) {
     if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false;

     Person person = (Person) o;

     if (age != person.age) return false;
     return name.equals(person.name);
 }

 @Override
 public int hashCode() {
     int result = name.hashCode();
     result = 31 * result + age;
     return result;
 }

重写的equal()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高,但不可靠

所以每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(不必再用equal()去对比了),如果hashCode()相同,再使用equal()对比,如果为True,则表示这两个对象是真的相同了,这样大大提高了效率也保证了对比的准确性,实际应用就是Hash容器。

举例,创建Person类的HashSet集合,必须同时覆盖Person类的equals() 和 hashCode()方法。

HashSet不保存重复元素,靠的就是先判断hashCode是否相等,如果相等再进行equals()比较

HashMap底层也是通过HashSet实现,HashMap会覆盖键相同的值

原则总结(摘抄):

1.同一个对象(没有发生过修改)无论何时调用hashCode()得到的返回值必须一样。
如果一个key对象在put的时候调用hashCode()决定了存放的位置,而在get的时候调用hashCode()得到了不一样的返回值,这个值映射到了一个和原来不一样的地方,那么肯定就找不到原来那个键值对了。

2.hashCode()的返回值相等的对象不一定相等,通过hashCode()和equals()必须能唯一确定一个对象。
不相等的对象的hashCode()的结果可以相等。hashCode()在注意关注碰撞问题的时候,也要关注生成速度问题,完美hash不现实。

3.一旦重写了equals()函数(重写equals的时候还要注意要满足自反性、对称性、传递性、一致性),就必须重写hashCode()函数。
而且hashCode()的生成哈希值的依据应该是equals()中用来比较是否相等的字段。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: equalshashcodeJava中用于比较对象相等性的方法。在使用时,我们需要重写这两个方法,以确保对象的相等性比较正确。 重写equals方法时,需要遵循以下原则: 1. 自反性:任何对象与自身比较应该返回true。 2. 对称性:如果a.equals(b)返回true,则b.equals(a)也应该返回true。 3. 传递性:如果a.equals(b)返回true,b.equals(c)也返回true,则a.equals(c)也应该返回true。 4. 一致性:如果两个对象没有发生变化,多次调用equals方法应该返回相同的结果。 5. 非空性:任何对象与null比较应该返回false。 重写hashcode方法时,需要遵循以下原则: 1. 如果两个对象相等,则它们的hashcode值必须相等。 2. 如果两个对象hashcode值相等,则它们不一定相等。 在重写equalshashcode方法时,需要注意以下几点: 1. equals方法中比较的属性应该是对象的所有属性,而不仅仅是部分属性。 2. hashcode方法中计算hashcode值的属性应该是equals方法中比较的属性。 3. 如果一个类是不可变的,那么可以使用缓存的hashcode值来提高性能。 4. 如果一个类是可变的,那么hashcode值应该根据对象的状态动态计算。 总之,重写equalshashcode方法是Java中非常重要的一部分,它们可以确保对象的相等性比较正确,从而避免出现一些难以调试的bug。 ### 回答2: 在JAVA中,equals()和hashCode()是Object类中的两个方法,用于对象之间的比较和哈希码的生成。对于一个自定义的类,可以通过重写equals()和hashCode()方法来实现自己的比较和哈希码生成的逻辑。 重写equals()方法的目的是比较两个对象是否相等。默认情况下,equals()方法会比较两个对象的内存地址是否相同,即判断是否是同一个对象。但是在许多情况下,我们需要比较对象的属性值来确定它们是否相等。因此,需要重写equals()方法来实现自定义的相等判断逻辑。通常,我们可以根据对象的属性进行比较,如果属性值都相等,就判定两个对象相等。 重写hashCode()方法的目的是为了生成对象的哈希码,以便在容器类中进行快速查找。哈希码是一个整数值,它是根据对象的属性值计算得出的一个唯一标识。在重写hashCode()方法时,通常要保证相等的对象必须拥有相等的哈希码。这是为了在使用哈希表等数据结构时,能够准确地找到对象。 在重写equals()和hashCode()方法时,还需要遵循一些规则。例如,如果两个对象通过equals()方法比较相等,那么它们的哈希码必须相等。另外,equals()方法必须满足自反性、对称性、传递性和一致性。 总之,通过重写equals()和hashCode()方法,我们可以实现自定义对象之间的相等判断和哈希码生成逻辑。这样可以保证对象在对比和查找操作中的准确性和高效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值