Thursday, June 4, 2009

Conveniences for equals, hashCode and compareTo

The Apache commons-lang library provides some nice conveniences to help with overriding equals, hashCode and compareTo. Here are some idioms you might use:

public boolean equals(Object obj)
{
    if (this == obj) {
        return true;
    }
    if (obj == null || this.getClass() != obj.getClass()) {
        return false;
    }
    MyObject other = (MyObject)obj;
    return new EqualsBuilder().append(this.id, other.id).isEquals();
}

public int hashCode()
{
    return new HashCodeBuilder(3, 13)
        .append(this.id).toHashCode(); // pick any two prime numbers
}

public int compareTo(Object obj) // assumes this class "implements Comparable"
{
    MyObject other = (MyObject)obj;
    return new CompareToBuilder().append(this.id, other.id).toComparison();
}

Just like StringBuffer, you can "append" as many fields as needed, in order to establish your object's identity (uses the builder design pattern). In my examples, I'm considering only my object's "natural identity", but you can likewise writeup other equality comparisons that consider multiple fields in your class:

return new EqualsBuilder()
    .append(this.name, other.name)
    .append(this.birthday, other.birthday)
    .append(this.city, other.city) // and etcetera, as needed
    .isEquals();

This facilitates not only overriding equals(Object), but writing up additional equality methods supporting various contracts. For in-depth details around the Commons Lang classes, visit Andrew Glover's writeup.

No comments:

Post a Comment