为什么重写equals还要重写hashcode?怎么重写hashcode?
一、hash表的存储方法?
hash表采用数组+链表+红黑树的存储结构。
用put()存储时,将key值转换成hash值,然后再转换成数组的下标,如果此处没有值,直接插入,若有值,则碰撞。碰撞之后,存储到链表中,链表长度大于8时,将其转换成红黑树。
hashcode()会将key值转换成hash值,hash值对数组长度取余后,得到数组下标。
不同的hash值取余可能会得到相同的数组下标,在用equals判断是否为相同的对象,若不同,则插入链表中。
- 若hash值不同,一定是不相同对象
- 若hash值相同,可能是相同对象,也可能是不相同对象。
二、为什么重写equals时还要重写hashcode?
可能会造成容器内出现两个内容一样的对象。若只重写了equals(),没有重写hashcode(),Object中的hashcode()会根据对象的引用地址来确定hash值,就会造成hashcode()判断出两个对象不一致,equals()判断一致,相同的对象内容散乱分布在hash表中,hash表中就出现了两个内容一样的对象。
三、怎么重写hashcode()?
利用equals()中比较两个对象是否相等时,涉及到的属性来重写hashcode().
对属性线性组合。
例如比较Person对象内容是否一致,属性有int age,String name
public int hashcode(){
return name.hashcode() + 23 * age;
//String类里的hashcode()已经重写过了
}