If a class implements Comparable , this assumes that instances of the class represent values โโof some type; generally, when classes encapsulate values, two different instances can exist that have the same value and therefore should be considered equivalent. Since the only equivalent for individual instances of objects is their redefinition of equals and hashCode , this means that things that implement Comparable should override equals and hashCode , unless the encapsulated values โโby which compare operations are globally unique (assuming that individual instances will never shall be deemed equivalent).
As a simple example, suppose the class includes a CreationRank field of type long ; each time an instance is created, this member is set to a value selected from a singleton AtomicLong , and Comparable uses this field to rank objects in the order they were created. No two different class instances ever report the same CreationRank ; therefore, the only way x.equals(y) should be true if x and y are on the same instance of the object โ exactly the way equals and hashCode work by default.
BTW having x.compare(y) zero in return, it usually follows that x.equals(y) will return true, and vice versa, but there are times when x.equals(y) can be false, but x.compare(y) must nonetheless return zero. This may be the case when an object encapsulates some properties that can be ranked, and others that cannot. Consider, for example, the hypothetical FutureAction type, which encapsulates a DateTime and an implementation of the DoSomething interface. Such things can be ranked based on encapsulated dates and times, but there can be no sensible way to rank two elements that have the same date and time but different actions. Having the equals message false, and compare reports that zero will make more sense than pretending that explicitly nonequivalent elements should be called "equal."
source share