What does a good equals method look like?
EqualsVerifier checks if you wrote your equals
method the right way, but what is the right way?
Let’s say we have a class that looks like this:
equals
A good equals
method for this class looks like this:
This makes use of Java 17’s pattern matching for instanceof feature. java.util.Objects.equals(a, b)
takes care of null checks for non-primitive fields.
In prior versions of Java, it would look like this:
IDEs often generate an an instance check as the first line:
This is intended as an optimization. However, it turns out that, due to predictive branching optimizations that the JVM performs, this line actually makes equals
slower in most cases, not faster. Therefore, I recommend leaving it out. See this video for more details.
hashCode
If you override equals
in a class, you should always override hashCode
as well. A good hashCode
method for our Person
class looks like this:
Resources
If you want to know the reasoning behind all this, I recommend these resources:
- Effective Java, Third Edition, items 10 (Obey the general contract when overriding
equals
) and 11 (Always overridehashCode
when you overrideequals
)
Addison-Wesley, 2018
by Joshua Bloch
[book] - How to Write an Equality Method in Java
1 June 2009
by Martin Odersky, Lex Spoon, and Bill Venners
[link] - Not all equals methods are created equal
7 November 2017
by Jan Ouwens
[video] - Optimizing your equals() methods with Pattern Matching - JEP Cafe #21
9 November 2023
by José Paumard
[video]