Перегрузка Equals / GetHashCode в VB.NET для использования объектов в качестве словарных ключей
У меня есть словарь, ключи которого являются объектами Excel Range (нет, это не подлежит обсуждению), определяется следующим образом (тип 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 в Range кажется работающим (хотя и медленно)?
1 ответ
Возможно, вы захотите немного изучить, как работают хэш-коды. Хеш-коды на 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