說說JAVA的equals()和hashCode()

來源:互聯網
上載者:User

經常會有人問,如果重寫了equals方法,是不是一定要重寫hashcode方法呢? 答案是yes,因為如果不重寫,那麼基於hash結構的那些東東比如hashMap,HashSet等等會出現非你想象的結果。

why?看一下HashMap的源碼,get也是一樣的判斷邏輯:

public V put(K key, V value) {        if (key == null)            return putForNullKey(value);        int hash = hash(key.hashCode());        int i = indexFor(hash, table.length);        for (Entry<K,V> e = table[i]; e != null; e = e.next) {            Object k;            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {                V oldValue = e.value;                e.value = value;                e.recordAccess(this);                return oldValue;            }        }        modCount++;        addEntry(hash, key, value, i);        return null;    }

可以看出會先判斷hash,而hash是經過hashCode計算出來的,所以如果hashCode不相同,就會被當做兩個不同的索引值對,所以取出來的就未必是你想要的結果了。

從上面代碼也可以看出,如果只重寫hashCode而不重寫equals也是不行的,
if (e.hash == hash && ((k = e.key) == key || key.equals(k))),==比較的是記憶體位址與hashCode無關(這個結論寫個簡單的例子就可以驗證),每一個new都是新的對象,互不==的,所以大部分情況還是會走到equals,所以equals也同等重要,要重寫就兩者都重寫哦~其實,java對於hashCode是有約定的:
1. 在一個應用程式執行期間,如果一個對象的equals方法做比較所用到的資訊沒有被修改的話,則對該對象調用hashCode方法多次,它必須始終如一地返回同一個整數。在多次執行期間,當然可以不同。
2. 如果兩個對象根據equals(Object o)方法是相等的,則調用這兩個對象中任一對象的hashCode方法必須產生相同的整數結果。
3. 如果兩個對象根據equals(Object o)方法是不相等的,則調用這兩個對象中任一個對象的hashCode方法

如何理解第三條最後一句?散列的意義在於其速度,散列的速度是優於線性結構的,所以如果散列碼衝突的很多,後面跟著一個長長的鏈表,那散列還談何速度呢?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.