原理
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
hashCode()与equals()的相关规定
-
如果两个对象相等,则hashcode一定也是相同的
-
两个对象相等,对两个对象分别调用equals方法都返回true
-
两个对象有相同的hashcode值,它们也不一定是相等的
因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
hashCode() 的默认行为是对堆上的对象产生独特值,jvm自己分配的,不符合对象判断相等的需求。
如果没有重写 hashCode(),hashCode()的值是直接对堆对象进行计算的,则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
重写hashcode的示例
private volatile int hashcode;
@Override
public int hashCode() {
int result=hashcode;
if(result==0){
result=17;
result=31*result+areaCode;
result=31*result+prefix;
result=31*result+lineNumber;
hashcode=result;
}
return hashcode;
}