Java Object equals()和hashCode()

equals()和hashCode()區別

比較項 equals() hashCode()
從哪兒來 Object類 Object類
本質 兩個對象裏面包含的值(對象的引用或值類型的值) 對象實例的哈希碼
使用場景 判別相等 批量數據處理,判斷相等的預判
備註 hashCode()相等,equals()不一定相等 equals()相等,hashCode()一定相等
重寫 String、Math等封裝類都重寫了equals() 改寫equals時總是要改寫hashcode

源碼

Object的hashCode調用了java.lang.System.java類的identityHashCode()方法(native方法,c源碼)

    public int hashCode() {
        int lockWord = shadow$_monitor_;
        final int lockWordStateMask = 0xC0000000;  // Top 2 bits.
        final int lockWordStateHash = 0x80000000;  // Top 2 bits are value 2 (kStateHash).
        final int lockWordHashMask = 0x0FFFFFFF;  // Low 28 bits.
        if ((lockWord & lockWordStateMask) == lockWordStateHash) {
            return lockWord & lockWordHashMask;
        }
        return System.identityHashCode(this);
    }

Object 的equals方法

    public boolean equals(Object obj) {
        return (this == obj);
    }

Java語言對equals的要求

Java語言對equals()的要求如下,這些要求是必須遵循的:
A 對稱性:如果x.equals(y)返回是“true”,那麼y.equals(x)也應該返回是“true”。
B 反射性:x.equals(x)必須返回是“true”。
C 類推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那麼z.equals(x)也應該返回是“true”。
D 一致性:如果x.equals(y)返回是“true”,只要x和y內容一直不變,不管你重複x.equals(y)多少次,返回都是“true”。

任何情況下,x.equals(null),永遠返回是“false”;x.equals(和x不同類型的對象)永遠返回是“false”

hashCode的約定

java.lnag.Object中對hashCode的約定:

  1. 在一個應用程序執行期間,如果一個對象的equals方法做比較所用到的信息沒有被修改的話,則對該對象調用hashCode方法多次,它必須始終如一地返回同一個整數。
  2. 如果兩個對象根據equals(Object o)方法是相等的,則調用這兩個對象中任一對象的hashCode方法必須產生相同的整數結果。
  3. 如果兩個對象根據equals(Object o)方法是不相等的,則調用這兩個對象中任一個對象的hashCode方法,不要求產生不同的整數結果。但如果能不同,則可能提高散列表的性能。

比如HashSet中,判別是否包含兩個相等的對象,是先檢索hashcode值,不等的情況下才會去比較equals方法

重寫HashCode()的原則

  • “不爲一原則”:不必對每個不同的對象都產生一個唯一的hashcode,只要HashCode的get()能夠得到put()放進去的內容就可以
  • “分散原則”:生成hashcode的算法儘量使hashcode的值分散一些, 不要很多hashcode都集中在一個範圍內,這樣有利於提高HashMap的性能

Reference

Equals and Hash Code

equals()和hashCode()區別

發佈了153 篇原創文章 · 獲贊 20 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章