Lombok @EqualsAndHashCode example
In this article, we will take a look at lombok @EqualsAndHashCode
annotation usage and configuration options with examples.
@EqualsAndHashCode
annotation is applied over a class and it generates java equals() and hashCode() methods automatically.
Without this annotation or a class without lombok support, you need to write these methods yourself as shown below
public class User { private String name; private int age; @Override public boolean equals(Object o) { // implementation } @Override public int hashCode() { // implementation }
With lombok, above class can be reduced to
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class User { private String name; private int age; }
This will automatically generate equals()
and hashCode()
methods internally.
Example,
public class EqualsAndHashCodeTest { public static void main(String[] args) { User u = new User(); u.setName("A"); u.setAge(22); System.out.println("Hashcode of first user is: " + u.hashCode()); // create second user User u1 = new User(); u1.setName("B"); u1.setAge(35); System.out.println("Hashcode of second user is: " + u1.hashCode()); System.out.println("Equals: " + u.equals(u1)); // change values u1.setAge(22); u1.setName("A"); System.out.println("Equals: " + u.equals(u1)); } }
Output is
Hashcode of first user is: 4844
Hashcode of second user is: 5612
Equals: false
Equals: true
Two user objects with different values are created and compared with equals()
, the result is false
.
When second user is given same values as the first user, equals()
returns true
.
Generated
hashCode()
takes all the fields of the class into account for generating hash code.Similarly,
equals()
method compares all the fields of class to confirm if two objects are equal or not.
If you want to skip some properties, use exclude option of @EqualsAndHashCode
as
@EqualsAndHashCode(exclude="age")
Now, equals()
will not compare this field while checking for equality of two objects. Also, hashCode()
will not consider it for generating hash code.
If there are more than one fields, they should be enclosed in an array.
@EqualsAndHashCode(exclude={"age", "name"})
exclude
option will soon deprecated. You must use @EqualsAndHashCode.Exclude
over the fields that need to be skipped. Example,
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class User { private String name; @EqualsAndHashCode.Exclude private int age; }
Example,
public class EqualsAndHashCodeTest { public static void main(String[] args) { User u = new User(); u.setName("A"); u.setAge(22); User u1 = new User(); u1.setName("A"); u1.setAge(35); System.out.println("Equals: " + u.equals(u1)); // true } }
Even though the age of both user objects is different, equals()
returns true
. This is because, age
field is excluded from comparison in equals()
.
Alternatively, you can mark fields that need to be included in equals()
and hashCode()
implementation with @EqualsAndHashCode.Include
as shown below
import lombok.EqualsAndHashCode; @EqualsAndHashCode(onlyExplicitlyIncluded = true) public class User { @EqualsAndHashCode.Include private String name; private int age; }
Note that with Include
option, you need to also set onlyExplicitlyIncluded
option to true
with @EqualsAndHashCode
to indicate that it should only include fields, that are explicitly stated.
@EqualsAndHashCode with parent class
If a class annotated with @EqualsAndHashCode
, extends another class, then its equals()
and hashCode()
methods do not consider parent class fields.
This makes the implementation of equals()
and hashCode()
faulty.
Lombok provides a solution in the form of callSuper
option. When set to true
, equals()
and hashCode()
methods also include parent class fields in generated implementation. Example,
import lombok.EqualsAndHashCode; public class Person { private Integer id; } @EqualsAndHashCode(callSuper = true) public class User extends Person { private String name; private int age; }
Default value of callSuper
is false
.
If your class extends another class and you do not supply callSuper
value(either true
or false
), then a warning is generated
Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add ‘@EqualsAndHashCode(callSuper=false)’ to your type.
If your class does not extend any class but callSuper
is set to true raises a compile time error
Generating equals/hashCode with a supercall to java.lang.Object is pointless.
This is because this would mean that you are inheriting these methods(which is already being done anyway) and not generating any specific code.