String中equals()和hashCode()的实现
1 private final char value[]; 2 private int hash; // Default to 0 3 public boolean equals(Object anObject) { 4 if (this == anObject) { 5 return true; 6 } 7 if (anObject instanceof String) { 8 String anotherString = (String)anObject; 9 int n = value.length; 10 if (n == anotherString.value.length) { 11 char v1[] = value; 12 char v2[] = anotherString.value; 13 int i = 0; 14 while (n-- != 0) { 15 if (v1[i] != v2[i]) 16 return false; 17 i++; 18 } 19 return true; 20 } 21 } 22 return false; 23 } 24 public int hashCode() { 25 int h = hash; 26 if (h == 0 && value.length > 0) { 27 char val[] = value; 28 29 for (int i = 0; i < value.length; i++) { 30 h = 31 * h + val[i]; 31 } 32 hash = h; 33 } 34 return h; 35 }
1、String的数据是final的,即一个String对象一旦创建,便不能修改;形如String s = “hello”; s = “world”;的语句,当s = “world”执行时,并不是字符串对象的值变为了”world”,而是新建了一个String对象,s引用指向了新对象。
2、String类将hashCode()的结果缓存为hash值,提高性能。
3、String对象equals()相等的条件是二者同为String对象,长度相同,且字符串值完全相同;不要求二者是同一个对象。
4、String的hashCode()计算公式为:s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]
关于hashCode()计算过程中,为什么使用了数字31,主要有以下原因:
1、使用质数计算哈希码,由于质数的特性,它与其他数字相乘之后,计算结果唯一的概率更大,哈希冲突的概率更小。
2、使用的质数越大,哈希冲突的概率越小,但是计算的速度也越慢;31是哈希冲突和性能的折中,实际上是实验观测的结果。
3、JVM会自动对31进行优化:31 * i == (i << 5) – i
private
final
char
value[];
private
int
hash;
// Default to 0
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;
}