首先咱們先來看下String類的源碼:能夠發現String是重寫了Object類的equals方法的,而且也重寫了hashcode方法java
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; } /*返回哈希碼,String的哈希碼計算方式爲s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]*/ public int hashCode() { int h = hash; if (h == 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; } hash = h; } return h; }
那爲何在重寫equals方法時都要重寫hashCode方法呢:
首先equals與hashcode間的關係是這樣的:算法
一、若是兩個對象相同(即用equals比較返回true),那麼它們的hashCode值必定要相同;this
二、若是兩個對象的hashCode相同,它們並不必定相同(即用equals比較返回false) code
自個人理解:對象
因爲爲了提升程序的效率才實現了hashcode方法,先進行hashcode的比較,若是不一樣,那沒就沒必要在進行equals的比較了,這樣就大大減小了equals比較的次數,這對比須要比較的數量很大的效率提升是很明顯的,一個很好的例子就是在集合中的使用;源碼
咱們都知道java中的List集合是有序的,所以是能夠重複的,而set集合是無序的,所以是不能重複的,那麼怎麼能保證不能被放入重複的元素呢,但靠equals方法同樣比較的話,若是原來集合中之後又10000個元素了,那麼放入10001個元素,難道要將前面的全部元素都進行比較,看看是否有重複,歐碼噶的,這個效率可想而知,所以hashcode就應遇而生了,java就採用了hash表,利用哈希算法(也叫散列算法),就是將對象數據根據該對象的特徵使用特定的算法將其定義到一個地址上,那麼在後面定義進來的數據只要看對應的hashcode地址上是否有值,那麼就用equals比較,若是沒有則直接插入,只要就大大減小了equals的使用次數,執行效率就大大提升了。hash
繼續上面的話題,爲何必需要重寫hashcode方法,其實簡單的說就是爲了保證同一個對象,保證在equals相同的狀況下hashcode值一定相同,若是重寫了equals而未重寫hashcode方法,可能就會出現兩個沒有關係的對象equals相同的(由於equal都是根據對象的特徵進行重寫的),但hashcode確實不相同的。效率