我应该用我的字符串场的串联为一个哈希码? [英] Should I use a concatenation of my string fields as a hash code?

查看:87
本文介绍了我应该用我的字符串场的串联为一个哈希码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中的地址类,它看起来像这样:

I have an Address class in C# that looks like this:

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将它们串联,并从该字符串返回的哈希码

I'm implementing equality and so I need to override the hash code. At first I was going to use the hashcode formula from EJ but then I thought: These are all string fields, can't I just just use a StringBuilder to concatenate them and return the hash code from that string?

这就是:

var str = new StringBuilder();
str.Append(StreetAddress)
   .Append(RuralRoute)
   ...

return str.ToString().GetHashCode();



这有什么优势/劣势?为什么我不应该这样做?

What are the advantages/disadvantages of this? Why shouldn't I do it?

推荐答案

我会避免这样做,根本的理由是它创造了一串字符串毫无意义 - 尽管Kosi2801的有关使碰撞简单点也有关。 (我怀疑它不会的真正的创建多次碰撞,产生的磁场的性质,但是......)

I would avoid doing that simply on the grounds that it creates a bunch of strings pointlessly - although Kosi2801's point about making collisions simple is also relevant. (I suspect it wouldn't actually create many collisions, due to the nature of the fields, but...)

我会去对于简单易得的权利的算法我之前已经的在这个答案使用(感谢寻找它枪:) - 而这是在有效的Java上市,如你所说。在这种情况下,这将最终为:

I would go for the "simple and easy to get right" algorithm I've previously used in this answer (thanks for looking it up lance :) - and which is listed in Effective Java, as you said. In this case it would end up as:

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你可能要考虑的扩展方法:

That's not null-safe, of course. If you're using C# 3 you might want to consider an extension method:

public static int GetNullSafeHashCode<T>(this T value) where T : class
{
    return value == null ? 1 : value.GetHashCode();
}



然后你可以使用:

Then you can use:

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;
}

您的可能的创建参数数组方法实用工具使这个更简单:

You could create a parameter array method utility to make this even simpler:

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);
}

在大多数类型有涉及原语,让本来有些不必要的执行拳击,但在这种情况下,你只能引用。当然,你最终会不必要地创建一个数组,但你知道他们怎么说过早的优化...

In most types there are primitives involved, so that would perform boxing somewhat unnecessarily, but in this case you'd only have references. Of course, you'd end up creating an array unnecessarily, but you know what they say about premature optimization...

这篇关于我应该用我的字符串场的串联为一个哈希码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆