在VB.NET中重载Equals / GetHashCode以将对象用作字典键

时间:2012-04-09 14:37:47

标签: vb.net excel dictionary equals gethashcode

我有一个字典,其键是Excel范围对象(不,这是不可协商的),定义如下(类型CellProp是包含各种单元格属性的对象):

Dim dic As New Dictionary(Of Excel.Range, CellProp)(New RangeComparer())

因为键是对象,我需要重载Equals / GetHashCode函数。我目前的实施如下:

Class RangeComparer
Implements IEqualityComparer(Of Excel.Range)
Public Overloads Function Equals(ByVal x As Excel.Range, ByVal y As Excel.Range) As Boolean Implements IEqualityComparer(Of Excel.Range).Equals
    If x.Address(External:=True) = y.Address(External:=True) Then
        Return True
    Else
        Return False
    End If
End Function
Public Overloads Function GetHashCode(ByVal obj As Excel.Range) As Integer Implements IEqualityComparer(Of Excel.Range).GetHashCode
      Return obj.Count.GetHashCode
    End Function
End Class

然而,当一次向词典添加许多单元格(即数百个)时,这可能会很慢。最重要的是,有更快的方法吗?其次,为什么获取Range的Count属性的哈希码似乎有效(尽管很慢)?

1 个答案:

答案 0 :(得分:3)

您可能想对how hash codes work进行一些研究。散列码是100%任意的,可由程序员定义。唯一重要的是,如果两个实例不相同,那么它们的哈希码应该是不同的。如果你有一个几乎所有哈希码都相同的集合(即count = 1),那么你的字典仍然可以正常工作,但它会降级为线性搜索,效率非常低。这是因为几乎所有实例都产生了哈希冲突,因此散列到桶中没有任何好处。

例如,您可以尝试的另一种哈希码算法是从单元格的名称生成一个,这应该有更少的哈希冲突:

Public Overloads Function GetHashCode(ByVal obj As Excel.Range) _
    As Integer Implements IEqualityComparer(Of Excel.Range).GetHashCode

  Return obj.Address(External:=True).GetHashCode

End Function