1. 程式人生 > >兩個物件值相同(x.equals(y) == true),但卻可有不同的 hash code,這句話對不對?

兩個物件值相同(x.equals(y) == true),但卻可有不同的 hash code,這句話對不對?

答:不對,如果兩個物件 x 和 y 滿足 x.equals(y) == true,它們的雜湊碼(hash code)應當相同。Java 對於 eqauls 方法和 hashCode 方法是這樣規定的:(1)如果兩個物件相同(equals 方法返回 true ),那麼它們的 hashCode 值一定要相同;(2)如果兩個物件的 hashCode 相同,它們並不一定相同。當然,你未必要按照要求 去做,但是如果你違背了上述原則就會發現在使用容器時,相同的物件可以出現在 Set 集合中,同時增加新元素 的效率會大大下降(對於使用雜湊儲存的系統,如果雜湊碼頻繁的衝突將會造成存取效能急劇下降)。
補充:關於 equals 和 hashCode 方法,很多 Java 程式都知道,但很多人也就是僅僅知道而已,在 Joshua Bl och 的大作《Effective Java》(很多軟體公司,《Effective Java》、《Java 程式設計思想》以及《重構:改善既 有程式碼質量》是 Java 程式設計師必看書籍,如果你還沒看過,那就趕緊去亞馬遜買一本吧)中是這樣介紹 equals 方 法的:首先 equals 方法必須滿足自反性(x.equals(x) 必須返回true)、對稱性(x.equals(y) 返回true時,y.e quals(x) 也必須返回 true)、傳遞性(x.equals(y)和y.equals(z)都返回 true 時,x.equals(z)也必須返回tru e)和一致性(當x和y引用的物件資訊沒有被修改時,多次呼叫x.equals(y)應該得到同樣的返回值),而且對於 任何非 null 值的引用 x,x.equals(null) 必須返回 false。實現高質量的 equals 方法的訣竅包括:

  1. 使用 == 操作符檢查“引數是否為這個物件的引用”;
  2. 使用 instanceof 操作符檢查“引數是否為正確的型別”;
  3. 對於類中的關鍵屬性,檢查引數傳入物件的屬性是否與之相匹配;
  4. 編寫完 equals 方法後,問自己它是否滿足對稱性、傳遞性、一致性;
  5. 重寫 equals 時總是要重寫 hashCode;
  6. 不要將 equals 方法引數中的 Object 物件替換為其他的型別,在重寫時不要忘掉 @Override 註解。