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 the Author

author image
mkyong
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

avatar
10 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
12 Comment authors
DucQuoc.wordpress.comSham FiorinGabePJ Csubfire Recent comment authors
newest oldest most voted
tloszabno
Guest
tloszabno

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… Read more »

J C
Guest
J C

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;

GabeP
Guest
GabeP

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

Gostj
Guest
Gostj

>>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.

subfire
Guest
subfire

thanks!

Eugene Brusov
Guest
Eugene Brusov

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

Anjith Sasindran
Guest
Anjith Sasindran

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
Guest
Gostj

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).

don2x
Guest
don2x

Thank you for this.

DucQuoc.wordpress.com
Guest
DucQuoc.wordpress.com

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)

Sham Fiorin
Guest
Sham Fiorin

Very good this article, really helped me. Thanks…

Chris
Guest
Chris

Great post. Thanks.

harshit rastogi
Guest
harshit rastogi

Thanks for sharing .