天天看點

兩個對象值相同(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 Bloch的大作《Effective Java》(很多軟體公司,《Effective Java》、《Java程式設計思想》以及《重構:改善既有代碼品質》是Java程式員必看書籍,如果你還沒看過,那就趕緊去亞馬遜買一本吧)中是這樣介紹equals方法的:首先equals方法必須滿足自反性(x.equals(x)必須傳回true)、對稱性(x.equals(y)傳回true時,y.equals(x)也必須傳回true)、傳遞性(x.equals(y)和y.equals(z)都傳回true時,x.equals(z)也必須傳回true)和一緻性(當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注解。           

複制