Explain Codes LogoExplain Codes Logo

Apache Commons equals/hashCode builder

java
equals-hashcode
java-7
best-practices
Alex KataevbyAlex Kataev·Jan 29, 2025
TLDR

Leverage EqualsBuilder and HashCodeBuilder from Apache Commons for concise, effective equals and hashCode methods. Ensuring accurate comparisons and hash distributions for objects.

import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; public class Person { private String name; private int age; @Override public boolean equals(Object that) { if (this == that) return true; // Quick equals check, cuz why not? It's free! if (that == null || getClass() != that.getClass()) return false; Person person = (Person) that; return new EqualsBuilder() .append(name, person.name) .append(age, person.age) .isEquals(); // Now that's how we roll for equals! } @Override public int hashCode() { return new HashCodeBuilder(17, 37) // Because 17 is prime and 37 is... just cool. .append(name) .append(age) .toHashCode(); // Voila! Works like a charm. } }

This snippet dodges the reflection bullet for an easier and more performant ride, smoothly handling equals and hashCode without lazy-load hiccups when mingling with Hibernate.

Step-by-step guide to equals and hashCode paradise

Java 7+ and Guava goodies

Unleash the power of Java 7+ and Guava for best-in-class equals and hashCode techniques. Avoid the performance trap of reflection and helper objects with Objects utility methods. Craving for extra sugar? Guava's com.google.common.base.Objects got your back!

Reference, null and class checks

Kick off your equals method with reference equality and class checks to quickly spot differences:

if (this == obj) return true; // It's a match made in heaven! Nah, just in memory. if (!(obj instanceof MyBean)) return false; // Completely different beans.

Got subclasses playing mischief with instanceof? Use getClass() to nail exact class matches:

if (obj == null || obj.getClass() != getClass()) return false; // Because apples != oranges.

Adding superclass' spice to equals

Invoking superclass' equals injects inherited state into equality, ensuring no part is left out:

@Override public boolean equals(Object obj) { if (!super.equals(obj)) return false; // Sorry darling, you're not my type. // Continue comparing fields of subclass... }

hashCode's performance dance

Juggling multiple primitive fields? Performance optimization is key. Individual hashing fields saves performance and extends lord hashCode()'s blessings all over:

@Override public int hashCode() { int result = fieldName1.hashCode(); // First hash in, more to follow. result = 31 * result + Integer.hashCode(fieldName2); // Mixing it up! // Hash in more fields... return result; // Perfectly balanced, as all things should be. }

Hibernate's special attention

Dancing with Hibernate? Be mindful of equals and hashCode. Lazy collections can cause unexpected side steps, and proxies can throw off accurate instanceof checks. Your safest bet? Stick with getClass().

IDE's helping hand

IDEs like Eclipse offer to auto-generate equals and hashCode methods. While they're lifesavers, always triple-check the autogenerated script and tailor them to your needs.

Catering to specific needs

Reflection or manual checks?

Reflection-based methods are enticingly fast for development but beware! They take a toll on performance and offer limited control over equality logic. In production, it's a risky bet.

Beyond Apache Commons

Apache Commons ain't everyone's cup of Java. Guava offers similar features, and Java 7 brought us Objects.equals() and Objects.hash(). Take a sip!

Hibernate? Handle with care!

Hibernate models are sensitive. Field-by-field comparison out of the box isn't gonna cut it. Understanding entity identity, lazy-loaded fields, and proxies are crucial.