Commons Lang CompareToBuilder
provides a builder
for compareTo( )
methods.
CompareToBuilder
can perform a comparison via reflection, or a comparison can be
customized by passing parameters to an instance of
CompareToBuilder
. The following example
demonstrates the use of the reflection builder to implement a
compareTo( )
method. This implementation compares
all nonstatic and nontransient member variables in both classes.
import org.apache.commons.lang.builder.CompareToBuilder; // Build a compareTo function from reflection public int compareTo(Object o) { return CompareToBuilder.reflectionCompare(this, obj); }
CompareToBuilder.reflectionCompare( )
takes two
objects and compares the non-static, nontransient member variables of
these objects. In Example 1-2, the comparison
involves the name properties of two
PoliticalCandidate
objects from Example 1-3, which are considered equal if both
firstName
and lastName
are
equal. reflectionCompare( )
ignores static fields
and transients; therefore, in Example 1-3,
averageAge
and fullName
do not
contribute to the automated comparison.
Example 1-3. Implementing compareTo( ) using a reflection builder
public class PoliticalCandidate { // Static variable private static String averageAge; // Member variables private String firstName; private String lastName; private transient String fullName; // Constructors // get/set methods // Build a compareTo function from reflection public int compareTo(Object o) { return CompareToBuilder.reflectionCompare(this, obj); } }
In addition to a comparison by reflection, the
CompareToBuilder
can be configured to compare two
objects by a set of variables in a particular order. The order of
comparisons plays a key role when a comparison involves multiple
member variables; this order is not specified when using the
reflectionCompare()
method. Assume that the default sorting
behavior for PoliticalCandidate
objects should be
lastName
and then firstName
; if
two objects have the same lastName
, then sort by
the firstName
. The following example demonstrates
a customization of the compareTo( )
method.
Calling append( )
specifies what variables will be
compared and in what order they will be compared. The order of the
calls to append( )
are backward—similar to
pushing an object onto the top of a stack. The last property
“pushed” onto the
CompareToBuilder
is the first property to be
compared. Objects are compared by last name, and first name is used
as a “tiebreaker.” Example 1-4 will compare two
PoliticalCandidate
objects by
lastName
, falling back to
firstName
only if the lastName
values were equal.
Example 1-4. Customizing a compareTo( ) method with CompareToBuilder
// A compare to that mimics the behavior of equals( ) public int compareTo(Object o) { int compare = -1; // By default return less-than if( o != null && PoliticalCandidate.class.isAssignableFrom( o.getClass( ) ) ) { PoliticalCandidate pc = (PoliticalCandidate) o; compare = (new CompareToBuilder( ) .append(firstName, pc.firstName) .append(lastName, pc.lastName)).toComparison( ); } return compare; }
Remember to keep the behavior of equals( )
and
compareTo( )
consistent to avoid problems when
sorting collections. Automating the compareTo( )
method via reflection may not compare objects in a way that is
consistent with equals( )
.
compareTo( )
methods provide the natural sorting
order for a set of objects, and they are frequently used when sorting
a collection of JavaBeans©. If you are trying to
sort a collection of beans, you are better off using the
BeanComparator
, which is described in Recipe 3.10.
Instead of capturing comparison logic in a compareTo()
method, consider using a Comparator
object. The Jakarta Commons Collections project contains a number of
supplements to the Comparator
interface, such
as
utilities to reverse and chain comparators.
Comparator
utilities are discussed in Chapter 4.
3.144.91.47