A neat Java 5.0 snippet to remove duplication of standard equality checks between unrelated classes (eg: to stop Checkstyle complaining).
public abstract class Equality<T> { public boolean areEqual(T thisObj, Object thatObj) { if (thisObj == thatObj) { return true; } if (thatObj == null) { return false; } if (thisObj.getClass() != thatObj.getClass()) { return false; } return haveEqualFields(thisObj, (T)thatObj); } protected abstract boolean haveEqualFields(T thisObj, T thatObj); }
Use it thus:
public class MyClass { private static final Equality<MyClass> EQUALITY = new Equality<MyClass>() { protected boolean haveEqualFields(MyClass thisObj, MyClass thatObj) { if (thisObj.foo == null) return thatObj.foo == null; return thisObj.foo.equals(thatObj.foo); } } private String foo; ... public boolean equals(Object obj) { return EQUALITY.equals(this, obj); } }
You can of course define the equality in a separate class, have hierarchies of related equalities, etc.
There’s a small syntax error, the definition of the Equality class should be…
public abstract class Equality {
and its subclass should be….
private static final EQUALITY = new Equality() {
I think this is a nice technique but I am wondering if it diverges too far from idiomatic Java and becomes an ‘alien artifact’?
Ah! I think I see that LiveJournal has in fact swallowed the greater than and less than signs surrounding the generic type declarations that are required to make this example work! As they have just been swallowed in my previous comment.
Let me see, does the standard HTML escape work???
public abstract class Equality<T> {
private static final EQUALITY = new Equality<MyClass> {
Thank you, I shall fix it!
In our case it makes the code more maintainable rather than less – equality methods now take up much less space, so we can concentrate on the rest of the code, and it’s easier to see which fields are responsible for equality (and check that they also apply to hashcode).
I wouldn’t use it for just a couple of objects, but we have five which do this and the list is growing.
I guess, as with all patterns, use if and only if appropriate. 🙂