Consider implementing compareTo and equals method

Consider implementating compareTo and equals method

Unlike the other methods the compareTo method is not declared in Object. Rather, it is the sole method in the Comparable interface. It is similar in character to Object’s equals method, except that it permits order comparisons in addition to simple equality comparisons, and it is generic. By implementing Comparable, a class indicates that its instances have a natural ordering.

Sorting an array/list of objects that implement Comparable is as simple as this:

Arrays.sort(a);
Collections.sort(a);

By implementing Comparable, you allow your class to interoperate with all of the many generic algorithms and collection implementations that depend on this interface. Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. If you are writing a value class with an obvious natural ordering, such as alphabetical order, numerical order, or chronological order, you should strongly consider implementing the Comparable interface:

public interface Comparable {
int compareTo(T t);
}

equals method is used to check if two objects are equal or not. To check if only the object references are equal, use ==. To check if the contents of the two objects are equal, use the equals method. If the two objects are equal, it will return true, otherwise false.

public boolean equals(Object anObject)
}

The general contract of the compareTo method is similar to that of equals. However, it is strongly recommended, but not strictly required, that (x.compareTo(y)== 0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is “Note: This class has a natural ordering that is inconsistent with equals.”

Both the equals and compareTo methods can be used for object’s comparison. The main differences between both are the following:

  • Any object can be passed as an argument to the equals method where as compareTo method only takes the type of object of the class in which this method is defined.
  • With compareTo method, more information can also be obtained like which object is greater and which object is smaller. equals method only checks whether the objects are equal or not.
  • To use compareTo method, Comparable interface needs to be implemented by the class where as in case of equals method, its inherited from the Object class and you only have to override it, in case it’s not already overridden.

Just as a class that violates the hashCode contract can break other classes that
depend on hashing, a class that violates the compareTo contract can break other classes that depend on comparison. Classes that depend on comparison include the sorted collections TreeSet and TreeMap, and the utility classes Collections and Arrays, which contain searching and sorting algorithms. The equality test imposed by the compareTo method should generally return the same results as the equals method. If this provision is obeyed, the ordering imposed by the compareTo method is said to be consistent with equals. If it’s violated, the ordering is said to be inconsistent with equals.

For example, consider the BigDecimal class, whose compareTo method is inconsistent with equals. If you create a HashSet instance and add new BigDecimal(“1.0”) and new BigDecimal(“1.00”), the set will contain two elements because the two BigDecimal instances added to the set are unequal when compared using the equals method. If, however, you perform the same procedure using a TreeSet instead of a HashSet, the set will contain only one element because the two BigDecimal instances are equal when compared using the compareTo method.

If a class has multiple significant fields, the order in which you compare them
is critical. You must start with the most significant field and work your way down. If a comparison results in anything other than zero (which represents equality), you’re done; just return the result. If the most significant fields are equal, go on to compare the next-most-significant fields, and so on. If all fields are equal, the objects are equal; return zero.

public int compareTo(PhoneNumber pn) {
// Compare area codes
if (areaCode < pn.areaCode) 
   return -1; 
if (areaCode > pn.areaCode)
   return 1;
// Area codes are equal, compare prefixes
if (prefix < pn.prefix) 
   return -1; 
if (prefix > pn.prefix)
   return 1;
// Area codes and prefixes are equal, compare line numbers
if (lineNumber < pn.lineNumber) 
   return -1; 
if (lineNumber > pn.lineNumber)
   return 1;
return 0; // All fields are equal
}

While this method works, it can be improved. Recall that the contract for compareTo
does not specify the magnitude of the return value, only the sign. You can take advantage of this to simplify the code and probably make it run a bit faster:

public int compareTo(PhoneNumber pn) {
// Compare area codes
int areaCodeDiff = areaCode - pn.areaCode;
if (areaCodeDiff != 0)
   return areaCodeDiff;
// Area codes are equal, compare prefixes
int prefixDiff = prefix - pn.prefix;
if (prefixDiff != 0)
   return prefixDiff;
// Area codes and prefixes are equal, compare line numbers
return lineNumber - pn.lineNumber;
}

Leave a Reply

Your email address will not be published. Required fields are marked *