hashCode是专门为具备hash特性的数据结构准备的,hashCode一般是根据对象的某些属性生成的,
- 只要重写 equals,就必须重写 hashCode(要保证下面的因果关系)
- 因为你重写equals方法,肯定是因为默认的equals方法不满足需求,通常是根据对象中某些字段来决定是否equal,而一旦equal了,那hashcode一定要相等,因为在hash特性结构中,碰撞(hashCode相等)的元素会放到一个碰撞结构(链表或树)里,然后仅在这个碰撞结构中判断他们是否equals,进而决定是否要覆盖,如果你将equals相等的结构放到不同的碰撞结构中,肯定会影响整个结构的覆盖语义,所以,一定要保证equals相等,hashCode一定相等这个规则。
- Jdk中集合实现就依赖了这些关系,如果你重写了equals()方法,你肯可能破坏了equals相等,hashCode一定相等的规则,这样就完全使结果不符合预期,出现各种重复存储等问题。
- 如果自定义对象作为 Map 的键,那么必须覆写 hashCode 和 equals。(因为99%情况下我们存进去的是POJO,会认为field相等就相等,但是默认的方法只有同一个对象时才会认为equals)
hashCode()和equals()方法定义在Object类中,所以Java中所有对象都有这2个方法。
默认hashCode()返回的是对象地址或对象地址衍生值,所以如果两个对象hashCode不相等,这两个对象就肯定不相等,而equals相等,hashCode一定要相等。
默认equals()方法返回的是是否同一个对象
单个对象上,看不出这2个方法有何不妥,如果是多个对象一起看,就容易发现,这两个方法往往不符合我们认知,通常,我们会认为某些field相等的对象就应该equals,比如String,或者诸如Integer等数据类型的对象。自定义对象也是如此,因为存入集合里的多数情况下是POJO,鉴定他们是否相等的依据往往是field值。
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
hashCode()方法返回的是一个对象的散列值,并不是唯一标识一个对象的ID,不同对象的hashcode是可以相同的。
hashCode()方法是专门来给具备hash特性的数据结构用的,在Java中就是各种hash特性的集合。
我们需要结合集合需要具备的能力来理解hashCode应该具备怎样的功能,以HashMap为例,它用来存储键值对,对于重复的对象需要覆盖掉,先使用hashCode()方法来确定槽的位置,如果没有碰撞,就可以直接存储进去,如果有碰撞,就需要用equals()方法来判断是否是同一个对象,如果不是,就覆盖。