I often see many different implementations for methods
equals(),
hashCode() and
toString(). There is a good and simple approach in Apache Commons Lang which I always use for this purpose. Classes
EqualsBuilder,
HashCodeBuilder and
ToStringBuilder from the package
org.apache.commons.lang.builder provide methods to build consistent and good equals() hashCode() and toString() methods of any class.
We can use either Java reflection or call successive
append method for our purpose. Assume we have the following Java class:
public class MyClass {
private String name;
private int count;
private List keys;
...
}
1) Use Java reflection:
@Override
public boolean equals(final Object obj)
{
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public int hashCode()
{
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}
2) Include fields manually:
@Override
public boolean equals(final Object obj)
{
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
MyClass mc = (MyClass) mc;
return new EqualsBuilder().append(name, mc.name).append(count, mc.count).append(keys, mc.keys).isEquals();
}
@Override
public int hashCode()
{
return new HashCodeBuilder(17, 37).append(name).append(count).append(keys).toHashCode();
}
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
append("name", name).append("count", count).append("keys", keys).toString();
}
In the second case we have more control and can decide which fields we want to compare and which not. And don't care about data types. They can be primitive, Collection, Map or something else.