fcl的設計者認為,如果能將任何物件的任何例項放到雜湊集合中,能帶來很多好處。但是這裡說一點,還是會存在,雜湊碼類似的情況,這一點大型**架構這本書中有介紹,最好做下md5演算法.為此,system.object提供了gethashcode,它能獲取任何物件的int32雜湊碼.如果你定義的型別重寫了equals方法,還應重寫gethashcode方法。如果你的型別重寫了equals方法,但是沒有重寫gethashcode方法,c#編譯器會發出一條警告,提示你重寫gethashcode方法,之所以重寫equals方法的同時要求重寫gethashcode的原因是由於在system.collection.hashtable型別、system.collection.generic.dictionary型別以及其他的一些集合的實現中,要求兩個物件必須有相等的雜湊值才被視為相等。所以重寫equals就必須重寫gethashcode,確保相等性演算法和物件雜湊碼演算法一致.
簡單分析下向集合中新增鍵值對的雜湊過程:
1、向集合中新增鍵值對,第一步是獲取鍵物件的雜湊碼
2、根據該雜湊碼(將雜湊碼作為標識),將鍵值對儲存到指定的雜湊桶中
再分析下根據鍵查詢集合中的對應的值的過程:
1、獲取鍵的雜湊碼
2、該雜湊碼標識了現在要以順序的方式搜尋雜湊桶
3、根據該雜湊碼查詢與指定鍵物件相等的鍵物件.
但是,採用這個演算法來儲存和查詢鍵,一旦修改了乙個鍵物件,鍵對應的雜湊碼並不會進行相應的更新,該雜湊碼對應的鍵值對還掛在這個hash碼下,所以這就導致了集合再也找不到這個物件。所以,需要修改哈西表中的鍵物件時,正確的做法是移出原來的鍵值對,
修改鍵物件,將新的鍵值對物件新增回雜湊表.
自定義gethashcode方法或許不是一件難事,但取決於資料型別和資料分布情況,可能並不容易設計出能返回良好分布值的雜湊演算法。
選擇演算法來計算型別例項的雜湊碼時,請遵守一下規則:
1、這個演算法要提供良好的隨機分布,使雜湊表獲得最佳的效能
2、可在演算法中呼叫基類的gethashcode方法,幷包含它的返回值,但一般不要呼叫object或valuetype的gethashcode方法,因為兩者的實現都與高效能雜湊演算法不沾邊.
3、演算法至少使用乙個例項字段
4、理想情況下,演算法使用的字段應該不可變,也就是說,欄位應在物件構造時初始化,在物件生存期"永不改變"
5、演算法執行速度盡量快
6、包含相同值的不同物件應返回相同的雜湊碼。例如,包含相同文字的兩個string物件應返回相同雜湊碼.
CLR via C 物件雜湊碼
fcl的設計者認為,如果能將任何物件的任何例項放到雜湊表集合中,能帶來很多好處。為此,system.object提供了虛方法gethashcode,它能獲取任意物件的int32雜湊碼。如果你定義的型別重寫了equals方法,還應該重寫gethashcode方法。型別定義equals之所以還要定義ge...
Java基礎 理解雜湊與雜湊碼
1.從hashmap說起 我們知道map以鍵值對的形式來儲存資料。有一點值得說明的是,如果要使用我們自己的類作為鍵,我們必須同時重寫hashcode 和 equals 兩個方法。hashmap使用equals方法來判斷當前的鍵是否與表中的鍵相同。equals 方法需要滿足以下5個條件 2.雜湊雜湊的...
Redis 物件 雜湊物件
每種型別的變數至少使用了兩種不同的編碼 1 五種物件的底層編碼 字串型別物件 redis encoding int redis encoding embstr redis encoding raw 列表型別的物件 redis encoding ziplist redis encoding linke...