FranXh
FranXh

Reputation: 4771

Implementing the comparator interface in java

When you implement the Comparator interface in Java, is it required to rewrite the equals method? The java compiler does not complain if I do not do that. But is that OK to do?

Upvotes: 1

Views: 2189

Answers (3)

Stephen C
Stephen C

Reputation: 718886

The Comparator<SomeClass> interface is implemented as a separate class to the SomeClass class. There is no need for SomeClass.equals(Object) to be consistent with the comparator. (Indeed, it would pretty much defeat the purpose of having a separate comparator object!)

On the other hand, if SomeClass implements Comparable<SomeClass> it is strongly recommended that equals(Object) and compare(SomeClass, SomeClass) to be consistent. The javadoc for Comparable says this:

"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."

"For example, if one adds two keys a and b such that (!a.equals(b) && a.compareTo(b) == 0) to a sorted set that does not use an explicit comparator, the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set's perspective."


The java compiler does not complain if I do not do that.

The Java compiler cannot determine whether equals and compare are consistent. (Or equals and hashcode for that matter.) It is theoretically impossible to do this in all cases, and beyond the "state of the art" in practice. And a simple test that you've overridden equals would give false warnings in some cases.

You can't rely on the compiler to point out logic errors in your application.


If the question is actually about the semantics of Comparable<T>.equals(Object), then the answer is in the javadocs:

"Note that it is always safe not to override Object.equals(Object). However, overriding this method may, in some cases, improve performance by allowing programs to determine that two distinct comparators impose the same order."


Ted Hopp commented thus:

"Actually, a Comparator is useful for sorting; there's no reason why making it consistent with equals() would "defeat the purpose". Generally, it's a good idea to make them consistent, although this is not a requirement."

First, Ted is misconstruing what I wrote. I said:

"It ..." (i.e. a hypothetical requirement of consistency between T.equals(Object) and Comparator.compare(T, T)` "... would defeat the purpose of having a separate comparator"

Second, it is neither a good idea or a bad idea for comparators to be consistent with equals. It entirely depends on the intended semantics of equals, and the intended purpose of the comparator.

  • If the comparator is used for ordering elements in a TreeSet, then inconsistency with equals is going to result in strange behavior.

  • If the comparator is used for ordering a list of objects for display purposes, then consistency with equals is likely to be irrelevant.

Upvotes: 2

VeeArr
VeeArr

Reputation: 6178

The JavaDoc for this method in the Comparator Interface says: "Note that it is always safe not to override Object.equals(Object). However, overriding this method may, in some cases, improve performance by allowing programs to determine that two distinct comparators impose the same order."

Specifically, note that the equals() method is used to compare a different Comparator to your implementation of Comparator, not to check if two objects of the templated type are equal.

Upvotes: 2

o_o
o_o

Reputation: 516

A Comparator<T> is an object that helps to compare two objects of type T. Its only method that you are required to implement is compare(o1, o2). It specifies an ordering for objects of the class T.
This does not require rewriting the equals method, though for consistency (and logic) if a comparator's compare() method returns 0 when comparing two objects o1 and o2, o1.equals(o2) and o2.equals(o1) should return true.

Javadoc: Comparator

Upvotes: 2

Related Questions