Reference equality

Two references, one object on the heap.

Two references that refer to the same object on the heap are equal. Period. If you call the hashCode() method on both references, you’ll get the same result. If you don’t override the hashCode () method, the default behavior (remember, you inherited this from class Object) is that each object will get a unique number (most versions of Java assign a hashcode based on the object’s memory address on the heap, so no two objects will have the same hashcode).

If you want to know if two references are really referring to the same object, use the == operator, which (remember) compares the bits in the variables. If both references point to the same object, the bits will be identical.

Object equality

Two references, two objects on the heap, but the objects are considered meaningfully equivalent.

If you want to treat two different Song objects as equal (for example if you decided that two Songs are the same if they have matching title variables), you must override both the hashCode() and equals() methods inherited from class Object.

As we said above, if you don’t override hashCode(), the default behavior (from Object) is to give each object a unique hashcode value. So you must override hashCode() to be sure that two equivalent objects return the same hashcode. But you must also override equals() so that if you call it on either object, passing in the other object, always returns true.

아무거나

Very important

If two objects have the same hash code value, they are NOT required to be equal. But if they’re equal, they MUST have the same hash code value.

This is because:

The point is that hash codes can be the same without necessarily guaranteeing that the objects are equal, because the “hashing algorithm” used in the hashCode() method might happen to return the same value for multiple objects. And yes, that means that multiple objects would all land in the same hash code bucket in the HashSet, but that’s not the end of the world. The HashSet might be a little less efficient, because if the HashSet finds more than one object in the same hash code bucket, it has to use the equals() on all those objects to see if there’s a perfect match.

a.equals(b) must also mean that a.hashCode() == b.hashCode().

But a.hashCode() == b.hashCode() does NOT have to mean a.equals(b)

HashSet

When you put an object into a HashSet, it calls the object’s hashCode method to determine where to put the object in the Set. But it also compares the object’s hash code to the hash code of all the other objects in the HashSet, and if there’s no matching hash code, the HashSet assumes that this new object is not a duplicate.

In other words, if the hash codes are different, the HashSet assumes there’s no way the objects can be equal!

But, two objects with the same hash code might not be equal, so if the HashSet finds a matching hash code for two objects —one you’re inserting and one already in the set—the HashSet will then call one of the object’s equals() methods to see if these hash code–matched objects really are equal

And if they’re equal, the HashSet knows that the object you’re attempting to add is a duplicate of something in the Set, so the add doesn’t happen.

You don’t get an exception, but the HashSet’s add() method returns a boolean to tell you (if you care) whether the new object was added. So if the add() method returns false, the new object is a duplicate of something already in the set.