hashCode 与 equals?

2022-01-01 146 0

这道题也是面试常问得——“你重写过 hashcode 和 equals 么,为什么重写 equals 时必须重写 hashCode ⽅法?”

什么是 hashCode 方法?

hashCode() 方法的作⽤是获取哈希码,它会返回⼀个 int 整数,定义在 Object 类open in new window中, 是一个本地⽅法。

public native int hashCode();

为什么要有 hashCode 方法?

hashCode 方法主要用来获取对象的哈希码,哈希码是由对象的内存地址或者对象的属性计算出来的,它是⼀个 int 类型的整数,通常是不会重复的,因此可以用来作为键值对的建,以提高查询效率。

例如 HashMapopen in new window 中的 key 就是通过 hashCode 来实现的,通过调用 hashCode 方法获取键的哈希码,并将其与右移 16 位的哈希码进行异或运算。

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

为什么重写 quals 时必须重写 hashCode ⽅法?

维护 equals()和 hashCode()之间的一致性是至关重要的,因为基于哈希的集合类(如 HashSet、HashMap、Hashtable 等)依赖于这一点来正确存储和检索对象。

具体地说,这些集合通过对象的哈希码将其存储在不同的“桶”中(底层数据结构是数组,哈希码用来确定下标),当查找对象时,它们使用哈希码确定在哪个桶中搜索,然后通过 equals()方法在桶中找到正确的对象。

如果重写了 equals()方法而没有重写 hashCode()方法,那么被认为相等的对象可能会有不同的哈希码,从而导致无法在集合中正确处理这些对象。

为什么两个对象有相同的 hashcode 值,它们也不⼀定相等?

这主要是由于哈希码(hashCode)的本质和目的所决定的。

哈希码是通过哈希函数将对象中映射成一个整数值,其主要目的是在哈希表中快速定位对象的存储位置。

由于哈希函数将一个较大的输入域映射到一个较小的输出域,不同的输入值(即不同的对象)可能会产生相同的输出值(即相同的哈希码)。

这种情况被称为哈希冲突。当两个不相等的对象发生哈希冲突时,它们会有相同的 hashCode。

为了解决哈希冲突的问题,哈希表在处理键时,不仅会比较键对象的哈希码,还会使用 equals 方法来检查键对象是否真正相等。如果两个对象的哈希码相同,但通过 equals 方法比较结果为 false,那么这两个对象就不被视为相等。

if (p.hash == hash &&
    ((k = p.key) == key || (key != null && key.equals(k))))
    e = p;

相关文章

深拷贝和浅拷贝?
== 和 equals 的区别?
final、finally、finalize 的区别?
final 关键字有什么作用?
17.成员变量与局部变量的区别有哪些?
18.静态变量和实例变量的区别?静态方法、实例方法呢?

发布评论