Conceptually, there are two hash functions. The first hash function, as you probably have guessed, is the key object's GetHashCode
method. The second hash function is a hash of the key returned by the first hash function.
So, imagine a hash table that has a capacity of 1,024 items, and you're going to insert two keys: K1
and K2
.
K1.GetHashCode()
returns 1,023. K2.GetHashCode()
returns 65,535
The code then divides the returned key by the hash table size and takes the remainder. So both of the keys map to position 1,023 in the hash table.
K1
is added to the table. When it comes time to add K2
, there is a collision. So the code resorts to the second hash function. That second hash function is probably a "bit mixer" (often the last stage in calculating a hash code) of some sort that randomizes the bits in the returned key. Conceptually, the code would look something like this:
int hashCode = K2.GetHashCode();
int slot = hashCode % 1024;
if (table[slot] != null)
{
int secondHashCode = BitMixer(hashCode);
slot = secondHashCode % 1024;
}
The point here is that the code doesn't have to keep track of multiple hash functions for the different keys. It knows that it can call Key.GetHashCode()
to get the object's hash code. From there, it can call its own bit mixer function or functions to generate additional hash codes.