• Post Reply Bookmark Topic Watch Topic
  • New Topic

equals() method  RSS feed

 
Pranshul Bajaj
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How to know when to override an equals() method and when not to?
 
Knute Snortum
Sheriff
Posts: 4281
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think it's safe to say when you are comparing two objects of the same class, you need to override equals.  I believe it also affects sorting, but I'll let someone more experienced confirm that.
 
Knute Snortum
Sheriff
Posts: 4281
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It looks like if you implement Comparable for sorting, you should override equals() to, although this is not technically necessary.

Javadoc for Comparable wrote:It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Knute Snortum wrote:. . . recommended . . . that natural orderings be consistent with equals. . . .
The equals() method returns true whenever two Objects are compared which are equivalent to each other by the definition you are applying to your class. So
System.out.println(myObject.equals(yourObject));
would in those circumstances print true.
The best explanation I can think of about ordering is in the Java™ Tutorials. Making a class implement Comparable implies that you are defining a total ordering, and you are saying:-
For every two instances of that class, x₁ and x₂, we can always say that one of the following three statements is true:-
  • 1: x₁ is greater than x
  • 2: x₁ is less than x
  • 3: x₁ is the same ranking as x
  • It would in theory be possible to have an ordering without overriding the equals() method, but let's see what happens if you both implement Comparable and override equals(); you normally would do both together. Let's have a Car class where equals() takes make and registrationNumber into consideration, and we then compare them by speed. So you have two cars whose toString methods return:-
    1=Ford, NV16 XNP 66mph
    2=Ford, NV16 XNP 72mph
    Now we have the barmy situation where System.out.println(car₁.equals(car₂)); displays true but your compareTo method tells you that car₁ is less than car₂. How daft! If you are going to return true from equals() you really ought to be returning 0 from compareTo. Now, let's imagine a third Car, whose toString method returns
    3=Mercedes, NA15 YFC 72mph
    Let's imagine that whoever wrote that class recovered competence long enough to remember to override hashCode() and did it correctly. Now let's add those three Car objects to a HashSet. The two Fords will be regarded as equal to each other using equals and hashCode, so only the first Ford will be added to the Set and the Set will contain one Ford and one Mercedes.
    Now let's try adding them to a TreeSet. You have two cars doing 72mph, and only one of them will be added; if you add them in the order 1 2 3, you will add the two Fords and not the Mercedes. We now have the situation where the actual contents of the Set and how it would be displayed with System.out.println(mySet); differs by the order of addition, and the contents of different Set implementations differs from each other.That is why happens if you implement compareTo wrongly; the second example shows a TreeSet going wrong because the implementation is here not consistent with equals.
    Remembering that compareTo shou‍ld be anti‑symmetrical:
    x, yx.compareTo(y) == 0 ⇒ y.compareTo(x) == 0 (1)
    You shou‍ld always implement compareTo so it follows equals():-
    x, yx.equals(y) ⇒ x.compareTo(y) == 0 (2)
    But implementing compareTo as consistent with equals means that equals() also follows compareTo():-
    x, yx.compareTo(y) == 0 ⇒ x.equals(y) (3)
    You can combine equations 2 and 3:-
    Consistency with equals ≙ ∀x, yx.equals(y) ⇔ x.compareTo(y) == 0
    Or every time equals() returns true, compareTo returns 0 and every time compareTo returns 0, equals returns true. QED


    Had you not overridden equals() in that car class, this is what would have happened:The errors are getting even better The order of printing in both HashSets might be different from that shown above.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!