Originally Posted by
lare96
took the time out to read this, hopefully will help me improve my code
question though, what does a 'good' hashcode implementation look like? I understand that if the Objects are equal then then the hashcodes must be equal as well, and I also understand that distinct hashcodes make hash collections perform better but I'm a bit reluctant to override the method for classes like Position
Code:
@Override
public int hashCode() {
return (x * y) + z;
}
would something like that be appropriate?
tl;dr what's an appropriate hashcode and what isn't
H3ll Ruler's post is sort-of correct (and you can learn that much from the Java tutorials page).
What you pasted is a bad hash code implementation - consider the following two positions:
Code:
Position first = new Position(1, 0, 0);
Position second = new Position(0, 1, 0);
Both of those will have a hash code of 0. The default eclipse one (and afaik IDEA) would be:
Code:
public int hashCode() {
final int prime = 31;
int result = prime + x;
result = prime * result + y;
return prime * result + z;
}
This is reasonable (particularly because 31 is a prime), but could be better. When you know the maximum values, and if they are small enough, you can make the hash code perfect, which is desirable to eliminate collisions (which are slow).
The height will only ever be 0-3, inclusive, so it will fit in 2 bits. This means we can fit the x and y values into 15 bits each (0-32,767), which is enough for RS coordinates.
Code:
public int hashCode() {
return z << 30 & 0xC0000000 | y << 15 & 0x3FFF8000 | x & 0x7FFF;
}
This is perfect as long as 0 <= x <= 2^15, 0 <= y <= 2^15, and 0 <= z <= 3 (and also technically isn't a hash function given these conditions, but it doesn't matter).
The reason the above post isn't quite correct is that there is an incorrect initial assumption:
Originally Posted by
H3ll Ruler
2. if the objects are equal their hashcodes should also be equal.
If these conditions are met then the hashcode will work.
A premise of this is that it won't work if two different objects (as determined by equals(), not identity) have identical hash codes, when it will - HashTables are designed to deal with collisions (but if there is a collision, it'll probably be slower). Also, for most objects it'll be impossible to have a perfect hash function, because there is more variety than can fit into 32 bits (or it's infeasible to have a surjective function for the input). This is the case with e.g. String and they still work as keys.