我有一个字典,其键是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属性的哈希码似乎有效(尽管很慢)?
答案 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