Let your IntelliJ IDEA generate good looking equals, hashCode and toString with Google Guava

THE PROBLEM

In the world of Java, we’re quite often in the need of writing equals, hashCode and toString methods. To be honest, this is usually only an boilerplate obligation.

Thanks to smart IDEs, we don’t usually do this by ourselves anymore. We just let and IDE to do the hard work. There is one problem though. The generated code is usually incredibly ugly. Let’s consider following POJO:

public class Beer {
    
    private String brand;
    private String type;
    private int degrees;
    private double alcoholPercentage;
	private List<String> ingredients;

	// constructor
	// getters, setters if needed
    
}

THE USUAL SOLUTION

All of the major IDEs have the ability of generating the methods I mentioned, but this is how hashCode, equals and toString would look like:

1. equals – long list of IF statements …

@Override
public boolean equals(final Object o) {
	if (this == o) {
		return true;
	}
	if (!(o instanceof Beer)) {
		return false;
	}

	final Beer beer = (Beer) o;

	if (Double.compare(beer.alcoholPercentage, alcoholPercentage) != 0) {
		return false;
	}
	if (degrees != beer.degrees) {
		return false;
	}
	if (!brand.equals(beer.brand)) {
		return false;
	}
	if (!ingredients.equals(beer.ingredients)) {
		return false;
	}
	if (!type.equals(beer.type)) {
		return false;
	}

	return true;
}

2. hashCode – confusing magic numbers, xors and shifts

@Override
public int hashCode() {
    int result;
    long temp;
    result = brand.hashCode();
    result = 31 * result + type.hashCode();
    result = 31 * result + degrees;
    temp = alcoholPercentage != +0.0d ? Double.doubleToLongBits(alcoholPercentage) : 0L;
    result = 31 * result + (int) (temp ^ (temp >>> 32));
    result = 31 * result + ingredients.hashCode();
    return result;
}

3. toString – nasty string concatenation

@Override
public String toString() {
    return "Beer{" +
            "brand='" + brand + '\'' +
            ", type='" + type + '\'' +
            ", degrees=" + degrees +
            ", alcoholPercentage=" + alcoholPercentage +
            ", ingredients=" + ingredients +
            '}';
}

SOLUTION WITH GOOGLE GUAVA

Maybe you’ve heard of Google Guava. Maybe you’re already using it. Anyway, Google Guava is a nice little library that provides lot of goodies for Java. Using Guava we can rewrite three methods above to better looking alternatives:

1. equals – army of IF statements transformed to chained call

@Override
public boolean equals(final Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
        return false;
    }
    final Beer other = (Beer) obj;
    return Objects.equal(this.brand, other.brand) && Objects
            .equal(this.type, other.type) && Objects
            .equal(this.degrees, other.degrees) && Objects
            .equal(this.alcoholPercentage, other.alcoholPercentage) && Objects
            .equal(this.ingredients, other.ingredients);
}

2. hashCode – one-liner

@Override
public int hashCode() {
    return Objects.hashCode(brand, type, degrees, alcoholPercentage, ingredients);
}

3. toString – consistent chained call

@Override
public String toString() {
    return Objects.toStringHelper(this)
            .add("brand", brand)
            .add("type", type)
            .add("degrees", degrees)
            .add("alcoholPercentage", alcoholPercentage)
            .add("ingredients", ingredients)
            .toString();
}

SETUP YOUR INTELLIJ IDEA

For the equals and hashCode, there is a plugin called Equals and HashCode Deluxe Generator from Michal Jedynak. You can install it directly within IntelliJ, just type CTRL + SHIFT + A (or CMD + SHIFT + A on Mac) and type Browse repositories. That should bring you to following dialog where you can search for the plugin:

IntelliJ IDEA Plugins Repository

Using the new equals and hashCode plugins is simple, you will have new context menu option equals() and hashCode() deluxe directly next to the old one. Just press ALT+INS (or CTRL+N on Mac) and you will see familiar generate menu:

IntelliJ IDEA Generate menu

As far as toString is concerned, we only have to create a new template in IntelliJ. Press ALT + INS and go to toString() menu option. Click on the Settings button and navigate to Templates tab. In the Templates tab click the + button:

IntelliJ IDEA toString template

Give to the new template a name (like Guava toString or so) and paste the following code into the editor:

public String toString() {
    #set ($autoImportPackages = "com.google.common.base.Objects")
    return Objects.toStringHelper(this)
    #foreach ($member in $members)
        .add("$member.name", $member.accessor)
    #end
        .toString();
}

Using new template is easy, just enter generate menu (ALT + INS), select toString() and be sure to pick the right template:

IntelliJ IDEA toString() template

And that’s it, enjoy!

About these ads

6 thoughts on “Let your IntelliJ IDEA generate good looking equals, hashCode and toString with Google Guava

  1. Pingback: 使用Intellij IDEA插件生成使用Guava的equals、hashCode 和toString方法 | Leton

  2. Nice article, one more step towards clear and highly maintainable code! Spotted one typo: “Browser repositories” should be “Browse repositories”, the extra “r” will cause no matches to be found when CTRL-SHIFT-A’ing.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s