Michal Vrtiak

About Michal Vrtiak

Michal is a freelancer currently located in Prague, Czech Republic with huge passion for Java platform. He is very enthusiastic about Dependency Injection, IntelliJ IDEA and loves to use both Spring and Java EE.

IntelliJ IDEA: Generate 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 Browser 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
 

Reference: IntelliJ IDEA: Generate equals, hashCode and toString with Google Guava from our JCG partner Michal Vrtiak at the vrtoonjava blog.

Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

4 Responses to "IntelliJ IDEA: Generate equals, hashCode and toString with Google Guava"

  1. Jan says:

    Put 10 developers in a room and there will be 10 views on how code should formatted, what looks pretty and what looks ugly. Beauty is in the eye of the beholder. This looks like (some) effort for no value add.

  2. Yann Banan says:

    Nice IntelliJ template. Thank you!

    Note that your hashcode is built on mutable fields, wich means you can get undesirable things like:

    Beer beer = new Beer(“Chimay”, “Trappiste”, 6, 8.0, Arrays.asList(“hop”, “water”));
    Set beers = new HashSet();
    beers.add(beer);
    beer.setDegrees(10);
    for (Beer birra : beers) {
    System.out.println(birra); // Beer{brand=’Chimay’, type=’Trappiste’, etc.
    }
    System.out.println(beers.contains(beer)); // FALSE!!!

Leave a Reply


2 + eight =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books