從解析String的hashCode和equals方法原始碼到hash衝突
阿新 • • 發佈:2018-11-30
經常被問到hashcode方法和equals方法還有== ,網上都有結論,但我們不能知其然卻不知其所以然。所以我們從string的hashcode和equals入手,探究這3者,先貼原始碼。
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { hhashcode= 31 * h + val[i]; } hash = h; } return h; }
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject;equalsint 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; }
1.string的hashcode主要程式碼 h = 31 * h + val[i];
遍歷所有字元,val[i]對應ASCII表中的值,將它與h*31累加。最終得出一個hash值,但我們可以從這個演算法得知,不同的字串有可能得出相同的hashcode值(概率很低)
比如2個val1[1,0];val2[31]; 我這裡直接將ASCII值代替進去了,它們運算後的h都是31,但它們代表的內容不同。
所以通過hashcode值判斷2個字串是否相等是不行的。
2.equals方法.
== : 它的作用是判斷兩個物件的地址是不是相等
equals方法先判斷2個字串==,假如2個字串都==了,就是同一個物件了,肯定就相等了。
然後遍歷2個字串,一一對應比較字元,假如都相等了,就說這2個字串內容一樣。
總結:equals方法比較了2個字串是否是同一個物件,並且比較它們的內容是否一樣。
如果是同一個物件那麼內容肯定一致,根據hashcode演算法它們的hash值也一樣,
不同物件,它們內容也可能一致,內容一致hash值也就一樣,
但是內容和物件都不一樣,它們的hash值有可能相同,這樣就出現了所謂的hash衝突。原因取決於hashcode的演算法(見1)
所以通過hash值來比較2個字串內容是否一致嚴格上是錯誤的。