第9條 覆蓋equals時總要覆蓋hashCode

2021-07-29 08:01:15 字數 1346 閱讀 2047

在每乙個覆蓋equals方法的類中,都必須覆蓋hashcode方法,如果不這麼做,會導致這個類無法結合所有基於雜湊的集合的正常使用,如hashmap,hashset,hashtable。

object規範中有這麼一條:

如果兩個物件根據equals(object)方法比較是相等的,那麼呼叫這物件中任意乙個物件的hashcode方法都必須產生同樣的整數結果。

因為對於兩個物件a和b,如果a.equals(b)為true,則代表a與b在邏輯上是相等的,但是object中的hashcode方法,則是根據物件的記憶體位址來生成hashcode,這也就會導致兩個邏輯上相等的物件的hashcode卻是不同的。這在使用基於hashcode的雜湊表(如hashmap)時會出現問題:

public

class

phonenumber

@override

public

boolean

equals(object o)

if(!(o instanceof phonenumber))

phonenumber pn = (phonenumber)o;

return pn.linenumber == linenumber

&& pn.prefix == prefix

&& pn.areacode == areacode;

}}

map

string> m = new hashmapstring>();

m.put(new phonenumber(707, 867, 5309), "jenny");

m.get(new phonenumber(707, 867, 5309)); //return

null

因為在hashmap中,會先根據傳入物件的hashcode找到相應的桶,然後再在桶中尋找相等的物件,換言之如果連兩個物件的hashcode都不同,那麼也不會去比較這兩個物件是否相等。

乙個好的hashcode方法將會為不同的物件產生不同的hashcode,在最理想的情況下,應該把集合中所有不相等的物件均勻分布到所有可能的值上。

在hashcode的計算過程中,可以將冗餘域(即可以通過參與計算的其它值計算出來的值)排除在外,還有必須排除equals方法中沒有的所有值,否則有可能出現兩個物件邏輯相等但是生成的不同的狀況。

如果乙個類中參與hashcode計算的變數都是不可變(final)的,而且hashcode計算的開銷又非常大,那麼可以在建立這個物件,或第一次使用hashcode時計算這個值,然後將hashcode儲存在這個物件內部。

覆蓋equals總要覆蓋hashCode

1 通過物件位址,判斷兩個物件是否相等 public native int hashcode 2 equals 在沒有覆蓋object的equals之前,相當於 public boolean equals object obj 為什麼覆蓋equals總要覆蓋hashcode 1 equals應該提供...

覆蓋equals時遵守通用約定

類的每個例項都只與它自身相等。1,類的每個例項本質都是唯一的。2,不關心類是否提供了 邏輯相等 的測試功能。3,超類以及覆蓋了equals,從超類繼承過來的行為對於子類也是合適的。4,類是私有的或是包級私有的,可以確定它的equals方法永遠不會被呼叫。equals方法實現了等價關係 1,自反性。x...

覆蓋equals時遵守通用約定

不覆蓋equals時,類的每個例項都只與它自己相等。如果類有自己的邏輯相等概念,且超類未覆蓋equals以實現期望的行為,這時需覆蓋equals。約定內容 1.自反性 對於任何非null的引用值x,x.equals x 必須返回true 2.對稱性 對於任何非null的引用值x和y,當且僅當y.eq...