If I have a simple Groovy class such as
class Address {
Integer streetNumber
String streetName
String state
String zip
Country country
}
Although I could write (or use an IDE to generate) hashCode
and equals
methods like:
boolean equals(o) {
if (this.is(o)) return true;
if (!o || getClass() != o.class) return false;
Address that = (Address) o;
if (streetNumber? !streetNumber.equals(that.streetNumber) : that.streetNumber!= null) return false;
if (streetName? !streetName.equals(that.streetName) : that.streetName!= null) return false;
if (state? !state.equals(that.state) : that.state!= null) return false;
if (zip? !zip.equals(that.zip) : that.zip!= null) return false;
if (country? !zip.equals(that.zip) : that.zip!= null) return false;
return true;
}
int hashCode() {
int result = (streetNumber ? streetNumber.hashCode() : 0);
result = 31 * result + (streetName ? streetName.hashCode() : 0);
result = 31 * result + (state ? state.hashCode() : 0);
result = 31 * result + (zip ? zip.hashCode() : 0);
return 31 * result + (country ? country.hashCode() : 0);
}
Although this will work fine, I feel I could be making better use of Groovy's dynamism to achieve the same thing in a lot less code. One approach that springs to mind is using .properties
to get a map of an object's property names and values. I can then iterate over these properties, calling hashCode()
or equals()
on each one to achieve the same result as above.
Before I go down this path, I just want to check whether anyone else has found a good solution to this problem. I'm a bit wary of rolling my own solution, because the consequences of messing up equals()
or hashCode()
are potentially dire and hard to track down.
Thanks, Don
I'm not a groovy developer, but I understood that from groovy 1.8 you can invoke the AST transformation using @EqualsAndHashCode on the type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With