This is kind of an academic point, but I feel I don't fully understand hash codes if I don't understand why this is recommended by books such as Effective Java and many SO questions.
Suppose:
public sealed class Point
{
private readonly int x;
private readonly int y;
//constructor ommited
//equals ommited
public override int GetHashcode()
{
int hash = 17; //why should the initial value be non-zero?
unchecked
{
hash = hash * 31 + x; //do not tell me why I should use primes - that is not the question
hash = hash * 31 + y;
return hash;
}
}
}
Now, supposedly, the reason for the initial value is that it reduces collisions where one of the components is zero.
I'm struggling to find any example where this helps.
Here is one example of a collision, but having an initial value makes no odds.
x y Hash Without initial value Hash With initial value
0 31 31 16368
1 0 31 16368
Ideally, I'm looking for a concrete example where the initial value prevents a collision.
My theory on why an initial value can never make a difference
//Given a prime p, initial value i, fields a,b,c, calculate hash h
h = i;
h = h*p + a;
h = h*p + b;
h = h*p + c;
Therefore:
h = ((i*p + a)*p + b)*p + c
= (ipp + ap + b )*p + c
= ippp + app + bp + c
Therefore the inital value i
will effect all hash codes in the same way by producing a constant value, in this case i*p
3.
17
here. And I get the word arbitary from Effective Java. – MannoPoint
class come from, considering there is a buil-in Point class in .NET this question makes zero sense because of the C# tag. – MoorishgetHashcode
/GetHashcode
is common to both langauges. Also, there is not a built-inPoint
class. There is a built-inPoint
struct. What's more, my Point class is immutable, so it's a different beast. – Manno17
is arbitary which means there is no reason. Its only attempt to make more unique values possible. – Moorish