Sunday 7 December 2008

Item 12: Consider implementing Comparable

Consider implementing Comparable interface in your classes.

The sole method of Comparable interface is compareTo. Used when instances have a natural ordering, especially value classes. Therefore this is not useful if you need to sort array of classes multiple different ways. It only allows one way to sort. Sorting is then easy with collections.

Arrays.sort(a);

This is needed to interoperate with all the many generic algorithms and collection implementations that use it, like TreeSet<>

The object compares with argument object, returns a negative integer if other object is smaller, zero if same and a positive integer if bigger. A compareTo method to match the contract must have reflexivity, symmetric and transitivity just like equals. If they are not followed, it could break collector classes that depend on it. The compareTo method could in theory compare different types of objects, unlike equals but it is normally not done. I looked around to determine how, but not sure. I have not done much programming in Java, using this group to learn. Does anyone know if this is ever useful?

A ClassClass Exception is thrown if it can't be compared.

There are a few differences between compareTo and equals. Comparable interface is templated and therefore staticly typed, the arguments do not need to be type checked or cast. Field comparisons are done by order not by equality. You must use compareTo or an explicit Comparator. For primitive fields, use relational operators < and >. For floating point fields use Double.compare or Float compare since the relational operators do not obey the general contract for these types.

The item also talks about order of comparison. This is obvious to me. You must determine the significance of each field, or you might not get the order you expect. Good programming practice in any language.

For integer fields you could just subtract the two fields and return the value. However, if the difference is larger than the type allows (one field is a very large positive number and one is a very large negative number), and the result could overflow the type. This is a very hard bug to find. Another good programming tip in any language.

No comments: