C# 對象哈希碼


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對象應返回相同哈希碼.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM