我应该用我的字符串字段的串联的散列码?
-
12-09-2019 - |
题
我在C#Address类看起来像这样:
public class Address
{
public string StreetAddress { get; set; }
public string RuralRoute { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
}
我实施平等,所以我需要重写的哈希码。起初,我打算用从EJ的哈希码公式,但转念一想:这些都是字符串字段,我不能只是只使用StringBuilder将它们串联,并从该字符串返回的哈希码
?即:
var str = new StringBuilder();
str.Append(StreetAddress)
.Append(RuralRoute)
...
return str.ToString().GetHashCode();
这有什么优点/缺点?为什么我不应该这样做呢?
解决方案
我会避免这样做,根本的理由是它创造了一串字符串的无谓 - 虽然Kosi2801的有关使碰撞简单点也有关。 (我怀疑它不会的真正的创造了许多冲突,由于场的性质,但是......)
我会去的“简单易得的权利”的算法我以前一直的在这个答案使用(感谢寻找它枪:) - 而这是在有效的Java上市,如你所说。在这种情况下,将最终成为:
public int GetHashCode()
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + StreetAddress.GetHashCode();
hash = hash * 23 + RuralRoute.GetHashCode();
hash = hash * 23 + City.GetHashCode();
hash = hash * 23 + Province.GetHashCode();
hash = hash * 23 + Country.GetHashCode();
hash = hash * 23 + PostalCode.GetHashCode();
return hash;
}
这不是空安全的,当然。如果您使用C#3你可能要考虑的扩展方法:
public static int GetNullSafeHashCode<T>(this T value) where T : class
{
return value == null ? 1 : value.GetHashCode();
}
然后,可以使用:
public int GetHashCode()
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + StreetAddress.GetNullSafeHashCode();
hash = hash * 23 + RuralRoute.GetNullSafeHashCode();
hash = hash * 23 + City.GetNullSafeHashCode();
hash = hash * 23 + Province.GetNullSafeHashCode();
hash = hash * 23 + Country.GetNullSafeHashCode();
hash = hash * 23 + PostalCode.GetNullSafeHashCode();
return hash;
}
您的可能的创建参数数组方法工具来使这个更简单:
public static int GetHashCode(params object[] values)
{
int hash = 17;
foreach (object value in values)
{
hash = hash * 23 + value.GetNullSafeHashCode();
}
return hash;
}
和与调用它:
public int GetHashCode()
{
return HashHelpers.GetHashCode(StreetAddress, RuralRoute, City,
Province, Country, PostalCode);
}
在大多数类型有涉及原语,让本来有些不必要的执行拳击,但在这种情况下,你只需要引用。当然,你最终会不必要地创建一个数组,但你知道他们说的过早的优化是什么?
其他提示
别别是,因为对象可以是不同的altough的哈希码是相同的。
想到
"StreetAddress" + "RuralRoute" + "City"
VS
"Street" + "AddressRural" + "RouteCity"
两者都将具有相同的散列码,但在字段不同的内容。
有关这样的事情,你可能想实现IEqualityComparer<Address>
:
public class Address : IEqualityComparer<Address>
{
//
// member declarations
//
bool IEqualityComparer<Address>.Equals(Address x, Address y)
{
// implementation here
}
int IEqualityComparer<Address>.GetHashCode(Item obj)
{
// implementation here
}
}
您也可以实现IComparable<Address>
拿到订购...
public string getfourDigitEncryptedText(string input) {
int hashCode = input.hashCode();
string hstring = (new StringBuilder()).append(hashCode).append("").toString();
string rev_hstring = (new StringBuilder(hstring)).reverse().toString();
string parts[] = rev_hstring.trim().split("");
int prefixint = 0;
for(int i = 1; i <= parts.length - 3; i++)
prefixint += integer.parseInt(parts[i]);
string prefixstr = "0";
if((new integer(prefixint)).toString().length() < 2)
prefixstr = (new StringBuilder()).append((new integer(prefixint)).toString()).append("5").toString();
else if((new integer(prefixint)).toString().length() > 2)
prefixstr = "79";
else
prefixstr = (new integer(prefixint)).toString();
string finalstr = (new StringBuilder()).append(prefixint).append(rev_hstring.substring(3, 5)).toString();
return finalstr;
}
不隶属于 StackOverflow