April 27, 2011

Groovy Goodness: Generate equals and hashcode Methods with EqualsAndHashCode Annotation

There are a lot of new bytecode generation annotation in Groovy 1.8. One of them is the @EqualsAndHashCode annotation. With this annotation an equals() and hashCode() method is generated for a class. The hashCode() method is implemented using Groovy's org.codehaus.groovy.util.HashCodeHelper (following an algorithm from the book Effective Java). The equals() method looks at all the single properties of a class to see of both objects are the same.

We can even include class fields instead of only properties for generating both methods. We only have to use includeFields=true when we assign the annotation.

To include calls to a super class we use the annotation attribute callSuper and assign the value true. Finally we can also exclude properties or fields from hashcode calculation or equal comparisons. We use the annotation attribute excludes for this and we can assign a list of property and field names.

import groovy.transform.EqualsAndHashCode

class User {
    String name
    boolean active
    List likes
    private int age = 37

def user = new User(name: 'mrhaki', active: false, likes: ['Groovy', 'Java'])
def mrhaki = new User(name: 'mrhaki', likes: ['Groovy', 'Java'])
def hubert = new User(name: 'Hubert Klein Ikkink', likes: ['Groovy', 'Java'])

assert user == mrhaki
assert mrhaki != hubert

Set users = new HashSet()
users.add user
users.add mrhaki
users.add hubert
assert users.size() == 2