登录

去注册

登录

注册

去登录

注册

每日一问 equals vs hashcode ?

xiaoyang   2019-09-04   收藏

作为一名 Java 开发者,这两个方法应该早已烂熟于心了。

今天我想问的是:

  1. 两个对象,equals 相同,hashcode 一定相同吗?
  2. hashcode 相同,equals 一定相同吗?
  3. 二者一篇在什么时候配合?如何配合?在哪些源码中可以看到类似的配合?
9

1.equals 相同,hashcode 一定相同
2.hashcode 相同,equals 不一定相同
3.HashMap、HashTable中配合。HashMap中的put方法就是先查看hashcode值,如果存在hashcode值就调用equals看元素是否存在,存在就更新,不存在就插入该新值,在插入大量非重复的数据时,可以有效的减少equals的调用,从而提高效率。

回复
3

a.按照java的设计思路,如果两个对象equals返回true,那么hashcode一定是相同的,反之则不一定。因为equals是反应两个对象的各属性是否相同,而hashcode是给出计算hash值的一个算法,在Java上hashcode是int值,其取值有限,所以对于两个对象,一定存在他们的属性不同而hashcode相同,甚至这两个对象可以属于完全不同的类;

b.但是equals和hashcode是两个Object的方法,我们当然可以通过重写这两个方法从而使存在两个对象equals返回false,而hashcode相同(比如equals直接返回false,hashcode直接返回0),但是这与java设计这两个方法的初衷相违背了。

c.equals的使用场景是来判断两个对象各个字段是否相同,而hashcode是用于使用hash表的时候计算hash值的辅助(在hashmap里hash值就是通过hashcode计算得来的),hashmap查询的步骤就是先通过hashcode计算出hash值,然后就知道应该在哪一个链表里面查询,在通过equals来查询到具体的key。也就是说对于hashmap,一个key对象的hashcode决定了它应该被放在hashmap里的哪一个链表里面(还与当前hash表的容量有关,因为计算hash值的时候使用了容量的,((n - 1) & hash)才是hash表的hash值。),而equals方法决定了两个key对象在hashmap看来是否是同一个对象。

d.也就是说我们如果想实现两个属性不同的对象在hashmap里面不能能同时存在,就重写equals方法,如果想要根据自己的需求防止hash碰撞,就重写hashcode方法。

回复
3
  • 一定,因为 equals 为 true 表示两个对象指向同一个引用,所以它们的 hashcode 也是相同的
    以下这段 Object 的 hashCode() 方法注释,也可以表明这个事实:
    Note that it is generally necessary to override the {@code hashCode}
    method whenever this method is overridden, so as to maintain the
    general contract for the {@code hashCode} method, which states
    that equal objects must have equal hash codes.
    
  • 不一定,因为 hashcode 是 int 值,取值是有限的,而要存放的值是无限的,因此肯定会存在冲突,这也叫鸽巢原理。因此不同对象的 hashcode 可能相同
    即 hashcode 相同, equles 不一定为 true
    以下这段 Object 的 hashCode() 方法注释,也可以表明这个事实:
    It is <em>not</em> required that if two objects are unequal
    according to the {@link java.lang.Object#equals(java.lang.Object)}
    method, then calling the {@code hashCode} method on each of the
    two objects must produce distinct integer results.
    
  • 二者一般在散列表一个桶需要存储多个对象时配合
    先判断要存储的两个 key 的 hashcode 是否相同,若相同再判断 equls 是否 为 true
    HashMap 的增删查都有它们的配合使用
回复
1
1
  • 一定
  • 不一定
  • HashMap里面看到过,在put方法里面,先看下是否hashcode相等,如果相等的话就放入同一个桶,然后比较equals,如果相同的话就替换掉
回复
0

小缘在哪?

回复
0

关于第一点:重写equals方法不重写hashcode的情况下,equals相等hashCode并不一定相等。

回复
0

1.equals 相同,hashcode 一定相同
2.hashcode 相同,equals 不一定相同
3.一般在解决hash冲突的时候配合使用。HashMap中的解决hash冲突的原理就是这个,在进行put的时候就是先查看hashcode(并不是指对象的的hashcode,而是对key进行了一个hash映射)值,如果存在hashcode值就调用equals看元素是否存在,存在就更新,不存在就插入该新值,在插入大量非重复的数据时,可以有效的减少equals的调用,从而提高效率。

回复
0
  1. 一定
  2. 不一定
  3. 在所有hash数据集合中配合,hash用于快速定位,equals用于比较。
回复
0
  1. 第一个问题的答案时肯定的,一定会相同,二者都是同一个内存地址上的计算出来的 hashcode 能不一样?
  2. 第二个问题的答案是不一定的,因为可能会产出哈希碰撞,>>>>> 然后一条龙来了,后面的问题就会问哈希碰撞的原因以及解决方法,然后可能就会问 java 集合了.........
  3. 就是在判断对象到底是不是同一对象还要求性能的时侯,HashMap 中有配合确定是否 put 一个新的节点。
回复
0

刚才的回答,第一段注释是 Object 的 equals() 方法的,写错了。。

回复
0

equals相同hashcode一定相同,hascode相同equals不一定相同!问题3 不了解

回复

删除留言

确认删除留言,会导致相关评论丢失?

取消 确定