Концептуально, есть две хеш-функции. Первая хеш-функция, как вы, наверное, догадались, это метод GetHashCode
ключевого объекта. Вторая хеш-функция - это хэш ключа, возвращаемого первой хеш-функцией.
Итак, представьте себе хеш-таблицу, которая вмещает 1024 элемента, и вы собираетесь вставить две клавиши: K1
и K2
.
K1.GetHashCode()
возвращает 1,023. K2.GetHashCode()
возвращает 65 535
Затем код делит возвращаемый ключ на размер хеш-таблицы и принимает остаток. Таким образом, оба ключа соответствуют позиции 1023 в хэш-таблице.
K1
добавлено в таблицу. Когда приходит время добавить K2
, возникает коллизия. Таким образом, код прибегает ко второй хэш-функции. Эта вторая хеш-функция, вероятно, представляет собой «битовый микшер» (часто последний этап вычисления хеш-кода), который рандомизирует биты в возвращаемом ключе. Концептуально код будет выглядеть примерно так:
int hashCode = K2.GetHashCode();
int slot = hashCode % 1024;
if (table[slot] != null)
{
int secondHashCode = BitMixer(hashCode);
slot = secondHashCode % 1024;
}
Дело в том, что код не должен отслеживать несколько хеш-функций для разных клавиш. Он знает, что может вызвать Key.GetHashCode()
, чтобы получить хеш-код объекта. Оттуда он может вызывать собственную функцию или функции микшера битов для генерации дополнительных хеш-кодов.