Embracing the Messiness in Search of Epic Solutions

IntelliJ IDEA 14.1: Better equals(), hashCode() and toString()

Posted

in

,

PROBLEM

Let’s assume we want to create the default equals(), hashCode() and toString() with the following bean:-

public final class Person {
    private final String name;
    private final Collection<car> cars;

    public Person(final String name, final Collection<car> cars) {
        this.name = name;
        this.cars = cars;
    }

    public String getName() {
        return name;
    }

    public Collection<car> getCars() {
        return cars;
    }
}

Most IDEs, including older version of IntelliJ, have code generation features that would create something similar to this:-

public final class Person {
    ...

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final Person person = (Person) o;

        if (name != null ? !name.equals(person.name) : person.name != null) {
            return false;
        }
        return !(cars != null ? !cars.equals(person.cars) : person.cars != null);
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (cars != null ? cars.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Person{" +
               "name='" + name + '\'' +
               ", cars=" + cars +
               '}';
    }
}

While it works, the generated code is usually crazy horrendous.

SOLUTION

With IntelliJ 14.x, it allows us to select templates from several proven libraries.

To generate equals() and hashCode(), select equals() and hashCode() option from the Generate pop-up dialog:-

There are several templates to choose from:-

Here’s an example of equals() and hashCode() using Guava and getter methods:-

public final class Person {
    ...

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final Person person = (Person) o;
        return Objects.equal(getName(), person.getName()) &amp;amp;&amp;amp;
               Objects.equal(getCars(), person.getCars());
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getName(), getCars());
    }
}

To generate toString(), select toString() option from the Generate pop-up dialog:-

Again, there are several templates to choose from:-

Here’s an example of toString() using Guava:-

public final class Person {
    ...

    @Override
    public String toString() {
        return Objects.toStringHelper(this)
                .add("name", name)
                .add("cars", cars)
                .toString();
    }
}

Comments

Leave a Reply