Main Tutorials

Java – How to override equals and hashCode

Some Java examples to show you how to override equals and hashCode.

1. POJO

To compare two Java objects, we need to override both equals and hashCode (Good practice).

User.java

public class User {
    private String name;
    private int age;
    private String passport;

	//getters and setters, constructor
}

	User user1 = new User("mkyong", 35, "111222333");
    User user2 = new User("mkyong", 35, "111222333");

    System.out.println(user1.equals(user2)); // false

2. Classic Way

The 17 and 31 hash code idea is from the classic Java book – effective Java : item 9

User.java

public class User {
    private String name;
    private int age;
    private String passport;

	//getters and setters, constructor

    @Override
    public boolean equals(Object o) {

        if (o == this) return true;
        if (!(o instanceof User)) {
            return false;
        }

        User user = (User) o;

        return user.name.equals(name) &&
                user.age == age &&
                user.passport.equals(passport);
    }

    //Idea from effective Java : Item 9
    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + name.hashCode();
        result = 31 * result + age;
        result = 31 * result + passport.hashCode();
        return result;
    }

}

2. JDK 7

For JDK 7 and above, you can use the new Objects class to generate the equals and hash code values.

User.java

import java.util.Objects;

public class User {
    private String name;
    private int age;
    private String passport;

	//getters and setters, constructor

    @Override
    public boolean equals(Object o) {

        if (o == this) return true;
        if (!(o instanceof User)) {
            return false;
        }
        User user = (User) o;
        return age == user.age &&
                Objects.equals(name, user.name) &&
                Objects.equals(passport, user.passport);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, passport);
    }

}

3. Apache Commons Lang

Alternatively, you can use the Apache Commons Lang EqualsBuilder and HashCodeBuilder function.

User.java

import org.apache.commons.lang3.builder;

public class User {
    private String name;
    private int age;
    private String passport;

	//getters and setters, constructor

     @Override
    public boolean equals(Object o) {

        if (o == this) return true;
        if (!(o instanceof User)) {
            return false;
        }

        User user = (User) o;

        return new EqualsBuilder()
                .append(age, user.age)
                .append(name, user.name)
                .append(passport, user.passport)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)
                .append(name)
                .append(age)
                .append(passport)
                .toHashCode();
    }

}

4. Test again

After overrides both equals and hashCode.


	User user1 = new User("mkyong", 35, "111222333");
    User user2 = new User("mkyong", 35, "111222333");

    System.out.println(user1.equals(user2)); // true

References

  1. Wikipedia : Java hashCode()
  2. The 3 things you should know about hashCode()
  3. JDK 7 Objects JavaDoc
  4. Apache Commons Lang
  5. HashCodeBuilder JavaDoc
  6. Stackoverflow : Overriding equals and hashCode in Java?

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
15 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
subfire
5 years ago

thanks!

Eugene Brusov
6 years ago

If user.name or user.password is null then you get crash in equals method

Anjith Sasindran
6 years ago

In the classic way of solving this (2. Classic Way), what if user.name is null. I was doing the same method, but my problem is some fields are null in my case. Now I’ve to add null checks everywhere individually. I guess this is the Java way of dealing with null checks.

Gostj
6 years ago

There is no need of null check in this case, just switch operands: write
name.equals(user.name)
instead of
user.name.equals(name)
But generally yes, in Java you must not use variable until it is checked for null (unless you are sure this is not the case for the variable).

m0rd3th
2 years ago

I read all this, then I go to eclipse and right click > generate hashCode and Equals > select fields > done

Sham Fiorin
5 years ago

Very good this article, really helped me. Thanks…

Gostj
6 years ago

>>The 17 and 31 hash code idea is from the classic Java book
It would be much better if you explain what is exactly the idea, not only refer to the source and post code snippet like some dogma. In fact, there is no explanations of something (except tloszabno’s posting). This is just disappointing.

Chris
6 years ago

Great post. Thanks.

harshit rastogi
7 years ago

Thanks for sharing .

tloszabno
8 years ago

Hello,
I have one comment to this article:
if (!(o instanceof User)) – if you use “instance of” instead of class.equals you broke the symetric rule ( a.equas(b) should give same result as b.equals(a) ).
Try imagine you create new class SuperUser which extends User with one additional boolean flag “is admin”, and new equals same as above, but with additional check condition for admin flag and with “instanceof” for SuperUser.
Now create normal user = new User(“mkyong”, 35, “111222333”); and adminUser = new SuperUser(“mkyong”, 35, “111222333”)
when you invkode user.equals(adminUser) result will be true (because equals from User class will be invoked and SuperUser is “instanceof” User, and other fields – know for User – are same) but when you call adminUser.equals(user) result will be false because equals from SuperUser will be invoked and User is not “instanceof” SuperUser).

Ben
4 years ago
Reply to  tloszabno

tloszabno, if you declare the override equals method final it saves the problem.
But you are right about the symmetric problem it can cause.

GabeP
5 years ago
Reply to  tloszabno

I think the override equals method of SuperUser is wrong, it should rely on or consider it is overriding User’s equals method

J C
5 years ago
Reply to  tloszabno

What’s the solution to this Mkyong, or tloszabno?
Should there also be a check … if (!(User instanceof o)) , so it becomes…

if (!(o instanceof User) || !(User instanceof o))
return false;

DucQuoc.wordpress.com
4 years ago

I think there should be some mention to Lombok’s @EqualsAndHashCode , which does correctly and efficiently.

(Especially it uses instanceof comparision instead of “getClass()” comparision – with the canEqual() compensation, subtle but worth understanding)

don2x
6 years ago

Thank you for this.