hashCode()
介绍
hashCode()
的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()
定义在 JDK 的 Object.java 中,这就意味着 Java 中的任何类都包含有 hashCode(
) 函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
为什么有hashCode()
在例如HashMap中会基于hashCode()
来确定Node放在哪个槽中,如果发现有两个对象hashCode相同再去比较equals(),这样就大幅度减少了equals()
方法的调用,提高了效率
hashCode()
与 equals()
的相关规定
- 如果两个对象相等,则 hashcode 一定也是相同的。
- 两个对象相等,对两个对象分别调用 equals 方法都返回 true。
- 两个对象有相同的 hashcode 值,它们也不一定是相等的。
- 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。
hashCode()
的默认行为是对堆上的对象产生独特值。如果没有重写hashCode()
,则该 class
的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。
为什么重写equals()
则一定需要重写hashcode()
因为会造成同一个散列表中出现多个相同的对象。
假设我们重写了Person的equals()方法,a、b是Person的实例对象,且a.equals(b) = true。
散列表基于hashCode()
计算出a对象hash = 1将他放在了table[1]。
基于hashCode()
计算出b对象hash = 2将他放在了table[2]。
这时就出现了重复元素。
重写equals的原则
1 自反性 --------- x.equals(x) 返回true
2 对称性 --------- 若x.equals(y)返回true,那么y.equals(x)返回true
3 传递性 --------- 若x.equals(y) 又有 y.equals(z) 那么 x.equals(z) 返回true
4 一致性 --------- 若x.equals(y)为true,那么无论调用多少次,始终返回true
5 非空性 --------- x.equals(null)的结果始终未false
String内部的重写
下面贴上String的源代码,学习一下大师级别人物是怎么重写的
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;
}
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;
}
根据String.hashCode()
算法来看,会有不同元素hashCode()相同,不过几率不会很大。