Si j'ai une simple classe Groovy tels queGroovy: générer des égaux et des méthodes hashCode
class Address {
Integer streetNumber
String streetName
String state
String zip
Country country
}
Bien que je pourrais écrire (ou utiliser un IDE pour générer) hashCode
et equals
méthodes comme:
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);
}
Bien que cela fonctionne bien, je pense que je pourrais faire un meilleur usage du dynamisme de Groovy pour obtenir la même chose avec beaucoup moins de code. Une approche qui vient à l'esprit utilise .properties
pour obtenir une carte des noms de propriété et des valeurs d'un objet. Je peux alors itérer sur ces propriétés, en appelant hashCode()
ou equals()
sur chacun d'eux pour obtenir le même résultat que ci-dessus. Avant de suivre ce chemin, je veux juste vérifier si quelqu'un d'autre a trouvé une bonne solution à ce problème. Je suis un peu méfiant de rouler ma propre solution, car les conséquences de foirer equals()
ou hashCode()
sont potentiellement désastreuses et difficiles à traquer.
Merci, Don
FYI, cette fonctionnalité n'est disponible que dans Groovy 1.8-beta-1. Groovy 1.8 est prévu pour la fin de 2010. Voir ici pour plus de détails http://groovy.codehaus.org/News –
et notez qu'il ne considère que _properties_ (pas les champs qui ont un public/protected/modificateur d'accès privé) sauf si vous spécifiez * includeFields = true * sur l'annotation –