hashCode()方法和equals()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致

equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?

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

hashCode()既然效率这么高为什么还要equals()呢?

因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:

  • equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。
  • hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。

为什么equals()相等,hashCode就一定要相等,而hashCode相等,却不要求equals相等?

如果equals相等,但是hashcode不相等,在散列表中的结果会错乱

equals相等,即默认逻辑上这个对象就是一个,但是hashcode不同,散列表hash获取索引的时候会到不同的entry,然后继续查找,会导致散列表错乱

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
 
    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

之所以hashCode相等,却可以equal不等,就比如ObjectA和ObjectB他们都有属性name,那么hashCode都以name计算,所以hashCode一样,但是两个对象属于不同类型,所以equals为false

为什么需要hashCode?

  • 通过hashCode可以很快的查到小内存块。
  • 通过hashCode比较比equals方法快,当get时先比较hashCode,如果hashCode不同,直接返回false

为什么重写equals 一定需要重写hashcode ?

hashCode()和equals()一样都是基本类Object里的方法,而和equals()一样,Object里hashCode()计算和内存地址无关JVM HashCode 和 内存地址的关系 如果是这样的话,那么我们相同的一个类,new两个对象,由于他们在内存里的地址不同,则他们的hashCode()不同,导致equals相等,但是hashcode不相等的情况出现。

所以这显然不是我们想要的,所以我们必须重写我们类的hashCode()方法,即一个类,在hashCode()里面返回唯一的一个hash值