不同的字符串,hashcode可能相同。
先看例子:
@Test public void test6(){ System.out.println("ABCDEa123abc".hashCode()); // 165374702 System.out.println("ABCDFB123abc".hashCode()); // 165374702 }
源碼:String.class
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { //上次一算出的hash值乘以31 然后再加上當前字符編碼值 h = 31 * h + val[i]; } hash = h; } return h; }
分析:int 在java中4個字節,[-2^31,2^31-1] (注意,數學表示方法,實際java用Math.pow(2,31))
int肯定會有一個上限,當字符長時產生的數值過大int放不下時會進行截取,一旦截取HashCode的正確性就無法保證了,所以這點可以推斷出HashCode存在不相同字符擁有相同HashCode。
那為什么HashMap可以照常獲取val呢?
@Test public void test6(){ System.out.println("ABCDEa123abc".hashCode()); // 165374702 System.out.println("ABCDFB123abc".hashCode()); // 165374702 Map<String,String> map = new HashMap<String,String>(); map.put("ABCDEa123abc","123"); map.put("ABCDFB123abc","321"); System.out.println(map.get("ABCDEa123abc")); System.out.println(map.get("ABCDFB123abc")); }
結果:
165374702
165374702
123
321
看下獲取的源碼:
(1)獲取Node[] 數組對應的Node元素, first = tab[(n - 1) & hash]
(2)如果不是Entry第一個元素,就指向Next。也就是說當hash相同時,只是說明所在的數組位置一樣,后續還是需要key比較;