My hashCode
method ensures that equal objects have equal hash codes. My implementation also guarantees that the contrapositive is true, in that equal hash codes imply object equality. Doing something like:
@Override
public boolean equals(Object obj) {
if (this == obj) {return true;}
if (obj == null) {return false;}
if (getClass() != obj.getClass()) {return false;}
return (obj.hashCode() == this.hashCode());
}
seems an obvious choice, but I don't see this often. Is this is a good idea in my case, or am I missing something?
Also, I'm not sure if this is relevant, but the hashCode
and equals
methods are in generated classes (and obviously are themselves generated). The reason I mention this is to highlight the fact that these methods will not be maintained manually per say. They are in classes that are created at compile time and are not intended to be changed unless the schema they are based on changes.
If, as the question says, your hashCode
implementation really does guarantee that unequal objects have unequal hash codes, then in principle there is nothing wrong with what you are doing. Your equals
method is checking a property that is equivalent to equality, so the behavior is as intended. You should re-check that guarantee, though; remember that no matter how clever you are, you can only store 32 bits of information in an int, which means that most non-trivial objects will necessarily have hash colisions.
However, there are a few caveats. First is clarity: if you implement equals
this way, anyone using your code has to look at your hashCode
implementation to find out what properties determine equality. Second is speed: if your hash code implementation is significantly slower than simply checking equality of the relevant properties (including boolean shortcutting in that calculation), then it may be worth re-implementing the logic in the equals
function to avoid the speed penalty. Third is coupling: implementing equals
in this manner means that it depends on that property of hashCode
, and any future change to hashCode
has to either preserve that property or move the logic into equals
.