Project Lombok - toString(), equals() and hashCode() Method Example


In this post, I will show you how to generate the toString(), equals() and hashCode() automatically in Java projects using Project Lombok annotations - @ToString, @EqualsAndHashCode.
Project Lombok is a very useful tool for Java projects to reduce boiler-plate code so in this example I will demonstrate how to automatically generate toString(), equals() and hashCode() automatically in Java projects using Project Lombok.

Video

This tutorial is explained in the below Youtube Video. Subscribe to my youtube channel to learn more about Spring boot at Java Guides - YouTube Channel.

Project Lombok Maven

Create a simple maven project using - How to Create a Simple Maven Project in Eclipse article.
Add the below dependency in your maven project pom.xml file:
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.4</version>
    <scope>provided</scope>
</dependency>

Adding the Lombok Plugin in IDE (Eclipse)

Follow below steps to install Lombok in eclipse for Windows:
  • Downloaded jar from https://projectlombok.org/download or use the jar which is downloaded from your maven build.
  • Execute command in terminal: java -jar lombok.jar
  • This command will open window as shown in the picture below, install and quit the installer and restart eclipse.

Without Project Lombok

Let's first look at a sample of code which has a boilerplate code. Let's create a User class with toString(), equals() and hashCode() methods:
package net.javaguides.lombok;

import java.time.LocalDate;

/**
 * 
 * @author Ramesh Fadatare
 *
 */
public class User {
    private long id;
    private String firstName;
    private String lastName;
    private int age;
    private LocalDate createdDate;
    private LocalDate updatedDate;
    private String gender;

    public long getId() {
        return id;
    }
    public String getFirstName() {
        return firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public int getAge() {
        return age;
    }
    public LocalDate getCreatedDate() {
        return createdDate;
    }
    public LocalDate getUpdatedDate() {
        return updatedDate;
    }
    public String getGender() {
        return gender;
    }
    public void setId(long id) {
        this.id = id;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setCreatedDate(LocalDate createdDate) {
        this.createdDate = createdDate;
    }
    public void setUpdatedDate(LocalDate updatedDate) {
        this.updatedDate = updatedDate;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((createdDate == null) ? 0 : createdDate.hashCode());
        result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
        result = prime * result + ((gender == null) ? 0 : gender.hashCode());
        result = prime * result + (int)(id ^ (id >>> 32));
        result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
        result = prime * result + ((updatedDate == null) ? 0 : updatedDate.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (age != other.age)
            return false;
        if (createdDate == null) {
            if (other.createdDate != null)
                return false;
        } else if (!createdDate.equals(other.createdDate))
            return false;
        if (firstName == null) {
            if (other.firstName != null)
                return false;
        } else if (!firstName.equals(other.firstName))
            return false;
        if (gender == null) {
            if (other.gender != null)
                return false;
        } else if (!gender.equals(other.gender))
            return false;
        if (id != other.id)
            return false;
        if (lastName == null) {
            if (other.lastName != null)
                return false;
        } else if (!lastName.equals(other.lastName))
            return false;
        if (updatedDate == null) {
            if (other.updatedDate != null)
                return false;
        } else if (!updatedDate.equals(other.updatedDate))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", age=" + age +
            ", createdDate=" + createdDate + ", updatedDate=" + updatedDate + ", gender=" + gender + "]";
    }
}
Note that we have also generated getter and setter methods for User class properties.

With Project Lombok

Let's eliminate boilerplate code using Lombok @ToString, @EqualsAndHashCode annotations:
package net.javaguides.lombok.equalshashcode;

import java.time.LocalDate;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@EqualsAndHashCode
public class UserLombokModel {
    private long id;
    private String firstName;
    private String lastName;
    private int age;
    private LocalDate createdDate;
    private LocalDate updatedDate;
    private String gender;

}

Testing

As you installed Lombok plugin in eclipse so we can test using a main() method to check whether equals(), hashCode(), and toString() methods generated properly or not:
package net.javaguides.lombok.equalshashcode;

import java.time.LocalDate;

public class LombokTest {
    public static void main(String[] args) {
        UserLombokModel lombokModel = new UserLombokModel();

        lombokModel.setId(100 L);
        lombokModel.setFirstName("Ramesh");
        lombokModel.setLastName("Fadatare");
        lombokModel.setAge(28);
        lombokModel.setGender("Male");
        lombokModel.setCreatedDate(LocalDate.now());
        lombokModel.setUpdatedDate(LocalDate.now());

        UserLombokModel lombokModel2 = new UserLombokModel();

        lombokModel2.setId(100 L);
        lombokModel2.setFirstName("Ramesh");
        lombokModel2.setLastName("Fadatare");
        lombokModel2.setAge(28);
        lombokModel2.setGender("Male");
        lombokModel2.setCreatedDate(LocalDate.now());
        lombokModel2.setUpdatedDate(LocalDate.now());

        // equals method
        System.out.println(lombokModel.equals(lombokModel2));

        // hashCode method
        System.out.println(lombokModel.hashCode());
        System.out.println(lombokModel2.hashCode());

        // toString method
        System.out.println(lombokModel.toString());
    }
}
Output:

Exclude Fields

We can also exclude some fields which we don’t want to include in toString(), equals() and hashCode() method by declaring exclude attribute in @ToString and @EqualsAndHashCode annotation.
For example, below is the code to exclude createdDate property in the User class:
package net.javaguides.lombok.equalshashcode;

import java.time.LocalDate;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString(exclude = "createdDate")
@EqualsAndHashCode(exclude = "createdDate")
public class UserLombokModel {
    private long id;
    private String firstName;
    private String lastName;
    private int age;
    private LocalDate createdDate;
    private LocalDate updatedDate;
    private String gender;

}
Now, if you check the .class file of above User.class, the content of User.class will be as below:
package net.javaguides.lombok.equalshashcode;

import java.time.LocalDate;

public class UserLombokModel {
    private long id;
    private String firstName;
    private String lastName;
    private int age;
    private LocalDate createdDate;
    private LocalDate updatedDate;
    private String gender;

    public void setId(long id) {
        this.id = id;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setCreatedDate(LocalDate createdDate) {
        this.createdDate = createdDate;
    }

    public void setUpdatedDate(LocalDate updatedDate) {
        this.updatedDate = updatedDate;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String toString() {
        return "UserLombokModel(id=" + getId() + ", firstName=" + getFirstName() + ", lastName=" + getLastName() + ", age=" + getAge() + ", updatedDate=" + getUpdatedDate() + ", gender=" + getGender() + ")";
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof UserLombokModel)) {
            return false;
        }
        UserLombokModel other = (UserLombokModel) o;
        if (!other.canEqual(this)) {
            return false;
        }
        if (getId() != other.getId()) {
            return false;
        }
        Object this$firstName = getFirstName();
        Object other$firstName = other.getFirstName();
        if (this$firstName == null ? other$firstName != null : !this$firstName.equals(other$firstName)) {
            return false;
        }
        Object this$lastName = getLastName();
        Object other$lastName = other.getLastName();
        if (this$lastName == null ? other$lastName != null : !this$lastName.equals(other$lastName)) {
            return false;
        }
        if (getAge() != other.getAge()) {
            return false;
        }
        Object this$updatedDate = getUpdatedDate();
        Object other$updatedDate = other.getUpdatedDate();
        if (this$updatedDate == null ? other$updatedDate != null : !this$updatedDate.equals(other$updatedDate)) {
            return false;
        }
        Object this$gender = getGender();
        Object other$gender = other.getGender();
        return this$gender == null ? other$gender == null : this$gender.equals(other$gender);
    }

    protected boolean canEqual(Object other) {
        return other instanceof UserLombokModel;
    }

    public int hashCode() {
        int PRIME = 59;
        int result = 1;
        long $id = getId();
        result = result * 59 + (int)($id >>> 32 ^ $id);
        Object $firstName = getFirstName();
        result = result * 59 + ($firstName == null ? 43 : $firstName.hashCode());
        Object $lastName = getLastName();
        result = result * 59 + ($lastName == null ? 43 : $lastName.hashCode());
        result = result * 59 + getAge();
        Object $updatedDate = getUpdatedDate();
        result = result * 59 + ($updatedDate == null ? 43 : $updatedDate.hashCode());
        Object $gender = getGender();
        result = result * 59 + ($gender == null ? 43 : $gender.hashCode());
        return result;
    }

    public long getId() {
        return this.id;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public int getAge() {
        return this.age;
    }

    public LocalDate getCreatedDate() {
        return this.createdDate;
    }

    public LocalDate getUpdatedDate() {
        return this.updatedDate;
    }

    public String getGender() {
        return this.gender;
    }
}

Reference

Comments