[英]GetHashCode() with string keys
嘿所有,我一直在閱讀實現.NET中對象的GetHashCode()覆蓋的最佳方法,並且我遇到的大多數答案涉及以某種方式將來自數字類型的成員的數字組合在一起來提出方法。 問題是,我有一個使用字母數字字符串作為其鍵的對象,我想知道是否有一些根本錯誤的東西只是使用內部ID作為鍵的字符串的對象,如下所示?
// Override GetHashCode() to return a permanent, unique identifier for
// this object.
static private int m_next_hash_id = 1;
private int m_hash_code = 0;
public override int GetHashCode() {
if (this.m_hash_code == 0)
this.m_hash_code = <>.m_next_hash_id++;
return this.m_hash_code;
}
是否有更好的方法為使用字母數字字符串作為鍵的對象提供唯一的哈希碼? (不,字母數字字符串的數字部分不是唯一的;其中一些字符串實際上根本沒有數字。)任何想法都將不勝感激!
您可以對對象中使用的非數字值調用GetHashCode()
。
private string m_foo;
public override int GetHashCode()
{
return m_foo.GetHashCode();
}
這不是為對象生成哈希的好模式。
重新理解GetHashCode()的目的很重要 - 它是一種生成對象標識屬性的數字表示的方法。 散列碼用於允許對象充當字典中的鍵,並在某些情況下加速復雜類型之間的比較。
如果您只是生成一個隨機值並將其稱為哈希碼,則您沒有可重復性。 具有相同鍵字段的另一個實例將具有不同的哈希碼,並且將違反HashSet,Dictionary等類所期望的行為。
如果您已在對象中擁有標識字符串成員,則只返回其哈希代碼。
對於計划覆蓋該方法的任何人來說,必須閱讀有關GetHashCode()
實現者的MSDN文檔 :
對實施者的說明
哈希函數用於快速生成對應於對象值的數字(哈希碼)。 散列函數通常特定於每個類型,並且為了唯一性,必須至少使用一個實例字段作為輸入。
哈希函數必須具有以下屬性:
如果兩個對象比較相等,則每個對象的GetHashCode方法必須返回相同的值。 但是,如果兩個對象的比較不相等,則兩個對象的GetHashCode方法不必返回不同的值。
只要沒有對對象狀態的修改來確定對象的Equals方法的返回值,對象的GetHashCode方法必須始終返回相同的哈希代碼。 請注意,這僅適用於當前應用程序的執行,並且如果再次運行應用程序,則可以返回不同的哈希代碼。
為獲得最佳性能,哈希函數必須為所有輸入生成隨機分布。
例如,String類提供的GetHashCode方法的實現為相同的字符串值返回相同的哈希碼。 因此,如果兩個String對象表示相同的字符串值,則它們返回相同的哈希碼。 此外,該方法使用字符串中的所有字符生成合理隨機分布的輸出,即使輸入聚集在特定范圍內(例如,許多用戶可能包含僅包含低128個ASCII字符的字符串,即使字符串可以包含任何65,535個Unicode字符)。
哈希碼不必是唯一的。 如果你的Equals
實現是正確的,那么為兩個實例返回相同的哈希碼是可以的。 m_next_hash_id
邏輯被破壞,因為它允許兩個對象具有不同的哈希碼,即使它們比較等於。
MSDN提供了一套關於如何實現Equals
和GetHashCode
的良好指令。 這里的一些例子根據對象字段的哈希碼實現了GetHashCode
是的,更好的方法是使用已有字符串的哈希碼。 如果字母數字字符串定義了您擁有的對象的標識,那么它的哈希碼對於對象的哈希碼會很好。
增加靜態字段並將其用作哈希碼的想法很糟糕。 哈希碼應該在可能值的空間內具有均勻分布。 除此之外,這確保了當用作哈希表中的鍵時它將表現良好。
我相信你通常希望GetHashCode()
返回一些通過它的值來識別對象的東西,而不是它的實例,如果我在這里理解這個想法,我認為你的方法將確保GetHashCode()
在兩個具有相同值的不同對象上返回不同的哈希只是因為它們是不同的實例。
GetHashCode()
旨在返回一個值,使您可以比較兩個對象值,而不是它們的引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.