I understand that returning the same value for each object is inefficient, but is it the most efficient approach to return distinct values for distinct instances?
If each object gets a different hashCode value then isn’t this just like storing them in an ArrayList?
No, it’s not actually.
Assuming your objects are going to be stored into a HashMap (or Set… doesn’t matter, we’ll use HashMap here for simplicity), you want your hashCode method to return a result in a way that distributes the objects as evenly as possible.
Hashcode should be unique for Objects that are not equal, although you can’t guarantee this will always be true.
On the other hand, if
a.equals(b)is true, thena.hashCode() == b.hashCode(). This is known as the Object Contract.Besides this, there are performance issues also. Each time two different objects have the same hashCode, they’re mapped to the same position in the HashMap (aka, they collide). This means that the HashMap implementation has to handle this collision, which is much more complex than simply storing and retrieving an entry.
There are also plenty of algorithms that rely on the fact that values are distributed evenly across a Map, and the performance deteriorates rapidly when the number of collisions increase (some algorithms assume a perfect hash function, meaning that no collisions ever occur, no two different values get mapped to the same position on the Map).
Good examples of this are probabilistic algorithms and data-structures such as Bloom Filters (to use an example that appears to be in fashion these days).