1. 程式人生 > >關於hashCode,你一定聽說過會重複,那麼你見過2個不同的字串hashCode值卻是相同的嗎

關於hashCode,你一定聽說過會重複,那麼你見過2個不同的字串hashCode值卻是相同的嗎

java中String.hashCode()方法的演算法如下:str.charAt(0) * 31n-1 + str.charAt(1) * 31n-2 + ... + str.charAt(n-1)

據說演算法中31這個數字是對英文字元進行優化後產生的一個最佳數字,但是碰上字母大小寫或是一些特殊字元,再或者是中文字元,它就不靈了,很容易重複,舉個例子:

Stringa="Aa";Stringb="BB";intaa=a.hashCode();intbb=b.hashCode();字串a與b的hashCode取值是相同的,都是2112

2017-08-01更新

大家關注度比較高,再來幾個中文例子,比如下面幾組的hashCode均相等
"柳柴"與"柴柕"  hashCode=851553"志捘"與"崇몈"  hashCode=786017

2018-03-19更新

製作相同hashcode的程式碼塊

System.out.println("\"柳志崇\".hashCode()="+"柳志崇".hashCode());
System.out.println("\"柳山왡\".hashCode()="+"柳山왡".hashCode());

int aa= '柳'*31*31+'志'*31+'崇' ;
System.out.println("aa=" + aa);


int ccint = (aa-  ('柳'*31*31+ '山'*31) );
System.out.println("ccint=" + ccint);
char cc = (char)ccint;

System.out.println("cc=" + cc);

4個知識點:

1.java中所有的物件都有一個父類Object,而Object類都有hashCode方法,也就是說java中所有的類均會有hashCode方法;
2.Object類的hashCode方法是native的,即是通用C語言來寫的,本文舉例使用的是String類,自己重寫了hashCode方法,演算法即如下:
String.hashCode()=str.charAt(0) * 31n-1 + str.charAt(1) * 31n-2 + ... + str.charAt(n-1)
3.String類的hashCode演算法是固定的,根據演算法就可以看到是可能會存在相同hashCode的
4.再強調一點,兩個String的hashCode相同並不代表著equals比較時會相等,他們兩者之間是沒有必然關係,這一點可以看看equals方法的實現


public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}