Working with booleans is simple and easy, right? Right. But sometimes it’s quite redundant. Conside a simple class called Human, which consists of a firstname, lastname and a weight.
The code on this page is trivial but in my experience very useful. There are many places where you can use the BooleanWorker class. Here’s an example for such a case:
public class Human {
private Integer weight;
private String firstname;
private String lastname;
//... skipped constructor, equals, hashCode, setters and getters
}
And this is what IntelliJ 7 generates for the equals() method:
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Human human = (Human) o;
if (firstname != null ? !firstname.equals(human.firstname) : human.firstname != null)
return false;
if (lastname != null ? !lastname.equals(human.lastname) : human.lastname != null)
return false;
if (weight != null ? !weight.equals(human.weight) : human.weight != null)
return false;
return true;
}
Quite nice code but not very good to read.
I prefer something like this:
public boolean myEquals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Human human = (Human) o;
BooleanWorker w = new BooleanWorker();
w.rememberEquals(firstname, human.firstname);
w.rememberEquals(lastname, human.lastname);
w.rememberEquals(weight, human.weight);
return w.isValid();
}
Of course, in comparision there’s one object creation and several method calls. But hey – I don’t care. It’s better to read now and more DRY at the same time. And the Java VM is optimizing anyway, so I think most of the code will be inlined. But I’m too lazy to check that.
Here’s the implementation.
package de.ansorgs.common.util;
/**
* This class helps building equals methods.
* It is not thread safe.
*
* License: Public domain. If you like please mention me as the original author.
*
* @author Joachim Ansorg, java at joachim-ansorg . de
*/
public class BooleanWorker {
private boolean result = true;
public boolean isValid() {
return result;
}
public final void remember(final boolean value) {
this.result = this.result && value;
}
public void remember(final Boolean value) {
remember(value.booleanValue());
}
/**
* Compares two objects. If a equals b the result stays the same, if they
* don't equal the result is set to false.
* This method accepts null values.
*
* @param a First object. May be null.
* @param b Second object. May be null.
*/
public void rememberEquals(final Object a, final Object b) {
if (!result) {
return;
}
if (a != null && b != null) {
remember(a.equals(b));
} else {
//at least a or b is null, so we return true if both are null
//otherwise we return false
remember(a == b);
}
}
}
Leave a Reply