For the Object class' equals method, the API says :

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

This means that until we override this method in our classes, this method would return true only if the both the references to our class are pointing to the same object in memory. Even if the two references point to 2 different objects that are exactly same, this method would return false. Am I right ?

About the interface Comparator's equals, the API says that

Note that it is always safe not to override Object.equals(Object).

but also says that

The ordering imposed by a Comparator c on a set of elements S is said to be consistent with equals if and only if (compare((Object)e1, (Object)e2)==0) has the same boolean value as e1.equals((Object)e2) for every e1 and e2 in S.

Now, if we only implement compare(), the object's equals method will always return false, even if the two references point to areas in the memory having a exact copy of each other's fields. So, it can never be consistent with equals.

Also, if the compare function serves the test for equality too, why do we need the equals method in the Comparator interface ?

Recommended Answers

All 2 Replies

Actually you have a small misunderstanding with that logic. The API says:
"The ordering imposed by a Comparator c on a set of elements S is said to be consistent with equals if and only if "

The API says at some point that the compare method does not have to be consistent with equals. Even if you implement it, you don't have to make sure that when equals returns true the compare method will also return 0.

The API only said:
"The ordering imposed by a Comparator c on a set of elements S is said to be consistent with equals if and only if "
They don't have to have the same behavior. It simply stated that if you want to say that they are consistent, the equals must behave like the compare. If they don't then that is also ok.

Also this: "if the compare function serves the test for equality too"
That is wrong. Just because 2 objects are equal with each other doesn't mean that their compare methods will return 0 and the other way around.

And we do need both.
Equals for determining equality and compare for sorting. Some classes like java.lang.String are consistent. The compare method and equals method have the same results. Others not.

And a practical example why they are different:
Assuming you have a person class with an id and a name:

class Person {
  private int id = 0;
  private String name = null;
}

In the equals method you will use the id to determine if 2 objects are equal. But if you may want to sort them by using the name attribute. These 2 objects:

Person p1 = new Person(1, "Jack");
Person p2 = new Person(2, "Jack");

Are not the same person. Many people have the same name but are not the same person. That is why we have the equals method:

public boolean equals(Object obj) {
  return id==((Person)obj).getId();
}

But if you want to sort them like in a book of addresses you will sort them by name:

public int compare() {
  return p1.getName().compareTo(p2.getName());
}

There are objects whose equals,compare behave the same and some do not. They don't have to be the same and you shouldn't use the compare==0 for equality.
The compare method is used for methods like: Arrays.sort for sorting. They take as argument the interface Comparable, in which they only use the compare method

commented: Good Explanation +5

Thanks a lot.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.