[英]How to implement GetHashCode for this situation?
我試圖實施IEqualityComparer<string>
基本上在某種程度上,(讓我們假設有兩個字符串兩個字符串比較x
和y
),如果x
開頭y
或y
與啟動x
它們應該被視為相等。
public bool Equals(string x, string y)
{
return x.StartsWith(y) || y.StartsWith(x);
}
public int GetHashCode(string obj)
{
return obj.GetHashCode();
}
當然實現Equals
方法很容易,但是GetHashCode
並非如此,我想不出任何正確實現它的方法,我編寫了一個如下的測試程序:
string[] values = {"hell", "hello", "foo", "fooooo"};
var result = values.Distinct(new StringComparer());
foreach(var x in result)
Console.WriteLine(x);
而且由於GetHashCode
我得到了錯誤的結果:
hell
hello
foo
fooooo
顯然,我可以通過從GetHashCode
返回所有值的相同值來強制調用Equals
方法,但是我想知道是否存在另一種實現方法,因為性能至關重要。 有沒有一種方法可以針對我的情況正確實現GetHashCode
方法?
注意:我知道它含糊不清,但找不到更好的標題,如果您有更好的主意可以自由編輯。
編輯:我將對Web URL使用此邏輯。 在我的情況下,前20個字符相等。 例如:
http://www.foo.com/bar?id=3
http://www.foo.com/bar?id=3&fooId=23
問題在於您對平等的定義:平等必須是可傳遞的。 但這不是您的情況。 取以下三個值:
* f
* freeze
* foo
然后f == freeze
,而foo == f
,但freeze != foo
。
另請參見有關實施等於方法的 MSDN,其中說:
(x.Equals(y) && y.Equals(z))
僅在x.Equals(z)
返回true時返回true。
正確的相等性定義會產生不同的值集,這些值被視為相等。 如果有這些代碼,則可以為每個集合定義一個“規范”表示形式,並計算規范值的哈希值,以便每個集合都有其哈希碼。 但這僅適用於可傳遞的運算(以及可交換和自反,這兩個屬性已包含在您的定義中)。
由於相等性的定義不是傳遞性的,因此無法定義此類集合,因此也無法找到合適的哈希碼。
但這也引發了其他問題。 以您的示例為例:
string[] values = { "hell", "hello", "foo", "fooooo" };
var result = values.Distinct(new StringComparer());
您期望將哪些值納入result
? 您是否一直想要最短的版本? 您的代碼將不能保證這一點,結果將取決於Distinct
的內部實現。
實現EqualityComparer
可能不是解決您實際問題的最佳方法。 您想達到什么目的?
由於字符串彼此相等(取決於您將其與哪個字符串進行比較),因此任何字符串都可以等於另一個。 因此,只有一種方法可以實現GetHashCode
方法。 對所有字符串返回相同的值:
public int GetHashCode(string obj) {
return 0;
}
這自然會帶來可怕的分布。 字典將具有O(n)查找時間,而不是O(1),但是它可以工作,並且是使它對這種相等比較起作用的唯一方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.