什么是DateRange类的好hashCode

时间:2010-08-19 20:32:00

标签: c# data-structures dictionary gethashcode

我有以下课程

public class DateRange
{
    private DateTime startDate;
    private DateTime endDate;
    public override bool Equals(object obj)
    {
        DateRange other = (DateRange)obj;
        if (startDate != other.startDate)
            return false;
        if (endDate != other.endDate)
            return false;
        return true;
    }
    ...
}

我需要将一些值存储在一个用DateRange键入的字典中,如:

Dictionary<DateRange, double> tddList;

我应该如何覆盖GetHashCode()类的DateRange方法?

5 个答案:

答案 0 :(得分:6)

我使用Effective Java中的这种方法来组合哈希:

unchecked
{
    int hash = 17;
    hash = hash * 31 + field1.GetHashCode();
    hash = hash * 31 + field2.GetHashCode();
    ...
    return hash;
}

在这种情况下,没有理由不能正常工作。

答案 1 :(得分:5)

答案 2 :(得分:4)

那么,请考虑一个好的哈希函数应具有的特性。 必须

  • 与Equals一致 - 也就是说,如果两个对象的Equals为真,则两个哈希码也必须相同。
  • 永不崩溃

应该

  • 非常快
  • 为类似输入提供不同的结果

我要做的是提出一个非常简单的算法;比如,从第一个的哈希码中取16位,从第二个哈希码中取16位,并将它们组合在一起。让自己成为代表性样本的测试用例;可能实际使用的日期范围,并查看此算法是否确实提供了良好的分布。

一个常见的选择是将两个哈希值合并在一起。这对于这种类型来说不一定是个好主意,因为似乎有人想要表示从X到X的零长度范围。如果你对两个相等的DateTimes的哈希值进行xor,你总是得到零,这看起来像是许多哈希碰撞的秘诀。

答案 3 :(得分:1)

你必须移动范围的一端,否则两个相等的日期将散列为零,这是我想象的非常常见的场景:

return startDate.GetHashCode() ^ (endDate.GetHashCode() << 4);

答案 4 :(得分:0)

return startDate.GetHashCode() ^ endDate.GetHashCode();

可能是一个好的开始。当startDate和endDate之间的距离相等但日期不同时,您必须检查是否获得了良好的分布。