A hash code is a single integer which represents the state of the object
that affects == comparisons.

All objects have hash codes.
The default hash code represents only the identity of the object,
the same way as the default == implementation only considers objects
equal if they are identical (see identityHashCode).

If == is overridden to use the object state instead,
the hash code must also be changed to represent that state.

Hash codes must be the same for objects that are equal to each other
according to ==.
The hash code of an object should only change if the object changes
in a way that affects equality.
There are no further requirements for the hash codes.
They need not be consistent between executions of the same program
and there are no distribution guarantees.

Objects that are not equal are allowed to have the same hash code,
it is even technically allowed that all instances have the same hash code,
but if clashes happen too often, it may reduce the efficiency of hash-based
data structures like HashSet or HashMap.

If a subclass overrides hashCode, it should override the
== operator as well to maintain consistency.