I have the following class:
public class Foo
{
int year;
string name;
int category;
}
Here is some example data:
2012 Test1 1000
2012 Test2 1000
2012 Test3 1000
2012 Test4 1000
2012 Test4 10
...
If I override GetHashCode all results are very similiar:
return year ^ name ^ category;
int hash = 13;
hash = hash * 33 + year.GetHashCode();
hash = hash * 33 + name.GetHashCode();
hash = hash * 33 + category.GetHashCode();
return hash;
What is a good hash function (with maximal distribution) for this situation?
Edit: Perhaps my understanding of the hash buckets is wrong. Go similar hash values to the same bucket?
"Test1".GetHashCode() --> -1556460260
"Test2".GetHashCode() --> -1556460257
One of the things I would recommend is to check if the String object is null or not.
The implementation seems to be fine, it would be similar but the hashcodes should be different as the main objective is to make them land in different buckets, hence helping out for further operations.
public int hashCode() { // Assuming year and category are String like name.
int hash = 31;
hash = hash * 331 + (this.year != null ? this.year.GethashCode() : 0);
hash = hash * 331 + (this.name != null ? this.name.GethashCode() : 0);
hash = hash * 331 + (this.category != null ? this.category.GethashCode() : 0);
return hash;
}
The few steps that I have learnt while Overriding hashCode are;
- Choose a prime hash e.g. 5, 7, 17 or 31 (prime number as hash, results in distinct hashcode for distinct object).
- Take another prime as multiplier different than hash is good.
- Compute hashcode for each member and add them into final hash. Repeat this for all members which participated in equals.
- Return hash.