Write simpler equals & hashCode Java methods using EqualsBuilder & HashCodeBuilder from Apache Commons
Last week I posted about how to implement a Hibernate-safe equals() method using instanceof and accessors (getters) in Eclipse. This showed that you don't want to be comparing the member variables directly but should use the accessor methods to protect against Hibernate's use of proxy objects.
My old colleague Guy Francis pointed out that rather than using Eclipse's generated (lengthy and rather ugly)
Both of these builders have a very useful reflection-based equals/hashcode method but that does a deep internal comparison of member variables so that is no good for use with Hibernate objects. One use that they don't really explain clearly (and hence the reason for this blog post) is whether you can use accessor (getter) methods instead of direct variable access when using these builders...
...well you can!
You create a new
Technorati Tags: Java, equals, hashCode, Apache Commons, Eclipse, Andrew Beacock
My old colleague Guy Francis pointed out that rather than using Eclipse's generated (lengthy and rather ugly)
equals
and hashCode
methods I should take a look at the Apache Commons EqualsBuilder
and HashCodeBuilder
.Both of these builders have a very useful reflection-based equals/hashcode method but that does a deep internal comparison of member variables so that is no good for use with Hibernate objects. One use that they don't really explain clearly (and hence the reason for this blog post) is whether you can use accessor (getter) methods instead of direct variable access when using these builders...
...well you can!
You create a new
EqualsBuilder
object inside your equals
method, append
access to any properties of your object that make it unique and then call the isEquals
method to test the properties. You do a very similar thing for hashCode
. This is my new version of last week's methods now using these builders rather than Eclipse's generated code:@OverrideThey are not only smaller and simpler, they are also much less error-prone and it's very clear which object properties are used to see if an object is 'equal'. I'm going to be using these builders from now on for all my
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person other = (Person) obj;
EqualsBuilder builder = new EqualsBuilder();
builder.append(getId(), other.getId());
builder.append(getName(), other.getName());
return builder.isEquals();
}
return false;
}
@Override
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(getId());
builder.append(getName());
return builder.toHashCode();
}
equals
and hashCode
methods!Technorati Tags: Java, equals, hashCode, Apache Commons, Eclipse, Andrew Beacock
Comments
Very helpful blog on the Apache Commons equals() and hashCode() helper classes.
I will add them to my bag of tricks. Thanks.
You rock from across the pond!
Rouy Dneirf,
Nhoj
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
final Foo other = (Foo) obj;
...
One area where it is useful though is when you are comparing Hibernate objects the getClass for your Hibernate objects returns a proxy to the real one the getClass won't return true.
Other than that it's a great idea.
A concise way to do it is:
return new HashCodeBuilder()
.append(getId())
.append(getName())
.toHashCode();
http://ravivenkatesan.blogspot.com/
I advice against using theese helpers, and recomend using the IDE generated implementations.
IDE generated methods are a good way to to too. This is somewhat of a stylistic decision where you should weigh the readability, maintainability, 3rd party library overhead, and performance. But as JVM's get better, the performance impact becomes negligible.
Javin