面试官问我,为什么重写equals函数,必须重写hashCode函数,我当时就懵住了。
然后扯天扯地,然后面试官瞬间就饱了,痛定思痛,写下这篇博客
首先看String的equals源码String重写了equals方法,引用指向同一个地址,一定返回true
。并且如果String包含的字符串
完全相同,同样返回true
.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
//重写后添加的代码
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
再看hashCode函数的源码
两个String包含的字符串如果完全相同,则返回的hash值也完全相同。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
官方建议重写了equals,一定要重写hashCode
就举最简单的例子,假定HashMap中以String为key,即HashMap
如果String只重写了equals方法,没有重写hashCode方法,同时put两个键完全相同
的键值对,类似、
, 则不会进行覆盖操作,即
object2替换object1
,而是会进行两次添加操作。
因为HashMap,hash值的计算完全依赖于key的hashCode值,如果没有重写hashCode
方法,会导致两个equals的字符串,映射到hash表中的不同位置。
参考文献java中的==、equals()、hashCode()源码分析
hashcode详解