Joshua Bloch says on Effective Java

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

Let's try to understand it with an example of what would happen if we override equals() without overriding hashCode() and attempt to use a Map.

Say we have a class like this and that two objects of MyClass are equal if their importantField is equal (with hashCode() and equals() generated by eclipse)

public class MyClass {
    private final String importantField;
    private final String anotherField;

    public MyClass(final String equalField, final String anotherField) {
        this.importantField = equalField;
        this.anotherField = anotherField;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((importantField == null) ? 0 : importantField.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final MyClass other = (MyClass) obj;
        if (importantField == null) {
            if (other.importantField != null)
                return false;
        } else if (!importantField.equals(other.importantField))
            return false;
        return true;
    }
}

Imagine you have this

MyClass first = new MyClass("a","first");
MyClass second = new MyClass("a","second");

Override only equals

If only equals is overriden, then when you call myMap.put(first,someValue) first will hash to some bucket and when you call myMap.put(second,someOtherValue) it will hash to some other bucket (as they have a different hashCode). So, although they are equal, as they don't hash to the same bucket, the map can't realize it and both of them stay in the map.


Although it is not necessary to override equals() if we override hashCode(), let's see what would happen in this particular case where we know that two objects of MyClass are equal if their importantField is equal but we do not override equals().

Override only hashCode

If you only override hashCode then when you call myMap.put(first,someValue) it takes first, calculates its hashCode and stores it in a given bucket. Then when you call myMap.put(second,someOtherValue) it should replace first with second as per the Map Documentation because they are equal (according to the business requirement).

But the problem is that equals was not redefined, so when the map hashes second and iterates through the bucket looking if there is an object k such that second.equals(k) is true it won't find any as second.equals(first) will be false.

Hope it was clear

Answer from Lombo on Stack Overflow
Top answer
1 of 16
726

Joshua Bloch says on Effective Java

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

Let's try to understand it with an example of what would happen if we override equals() without overriding hashCode() and attempt to use a Map.

Say we have a class like this and that two objects of MyClass are equal if their importantField is equal (with hashCode() and equals() generated by eclipse)

public class MyClass {
    private final String importantField;
    private final String anotherField;

    public MyClass(final String equalField, final String anotherField) {
        this.importantField = equalField;
        this.anotherField = anotherField;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((importantField == null) ? 0 : importantField.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final MyClass other = (MyClass) obj;
        if (importantField == null) {
            if (other.importantField != null)
                return false;
        } else if (!importantField.equals(other.importantField))
            return false;
        return true;
    }
}

Imagine you have this

MyClass first = new MyClass("a","first");
MyClass second = new MyClass("a","second");

Override only equals

If only equals is overriden, then when you call myMap.put(first,someValue) first will hash to some bucket and when you call myMap.put(second,someOtherValue) it will hash to some other bucket (as they have a different hashCode). So, although they are equal, as they don't hash to the same bucket, the map can't realize it and both of them stay in the map.


Although it is not necessary to override equals() if we override hashCode(), let's see what would happen in this particular case where we know that two objects of MyClass are equal if their importantField is equal but we do not override equals().

Override only hashCode

If you only override hashCode then when you call myMap.put(first,someValue) it takes first, calculates its hashCode and stores it in a given bucket. Then when you call myMap.put(second,someOtherValue) it should replace first with second as per the Map Documentation because they are equal (according to the business requirement).

But the problem is that equals was not redefined, so when the map hashes second and iterates through the bucket looking if there is an object k such that second.equals(k) is true it won't find any as second.equals(first) will be false.

Hope it was clear

2 of 16
379

Collections such as HashMap and HashSet use a hashcode value of an object to determine how it should be stored inside a collection, and the hashcode is used again in order to locate the object in its collection.

Hashing retrieval is a two-step process:

  1. Find the right bucket (using hashCode())
  2. Search the bucket for the right element (using equals() )

Here is a small example on why we should overrride equals() and hashcode().

Consider an Employee class which has two fields: age and name.

public class Employee {

    String name;
    int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;
        if (!(obj instanceof Employee))
            return false;
        Employee employee = (Employee) obj;
        return employee.getAge() == this.getAge()
                && employee.getName() == this.getName();
    }

    // commented    
    /*  @Override
        public int hashCode() {
            int result=17;
            result=31*result+age;
            result=31*result+(name!=null ? name.hashCode():0);
            return result;
        }
     */
}

Now create a class, insert Employee object into a HashSet and test whether that object is present or not.

public class ClientTest {
    public static void main(String[] args) {
        Employee employee = new Employee("rajeev", 24);
        Employee employee1 = new Employee("rajeev", 25);
        Employee employee2 = new Employee("rajeev", 24);

        HashSet<Employee> employees = new HashSet<Employee>();
        employees.add(employee);
        System.out.println(employees.contains(employee2));
        System.out.println("employee.hashCode():  " + employee.hashCode()
        + "  employee2.hashCode():" + employee2.hashCode());
    }
}

It will print the following:

false
employee.hashCode():  321755204  employee2.hashCode():375890482

Now uncomment hashcode() method , execute the same and the output would be:

true
employee.hashCode():  -938387308  employee2.hashCode():-938387308

Now can you see why if two objects are considered equal, their hashcodes must also be equal? Otherwise, you'd never be able to find the object since the default hashcode method in class Object virtually always comes up with a unique number for each object, even if the equals() method is overridden in such a way that two or more objects are considered equal. It doesn't matter how equal the objects are if their hashcodes don't reflect that. So one more time: If two objects are equal, their hashcodes must be equal as well.

🌐
Baeldung
baeldung.com › home › java › core java › overriding hashcode() and equals() for records
Overriding hashCode() And equals() For Records | Baeldung
January 16, 2024 - Java does provide the ability to override the default implementations of the equals() and hashCode() methods. For example, let’s say we decide that it is enough to assert the equality of two Movie records (having several attributes) if the titles and the year of release are identical.
🌐
GeeksforGeeks
geeksforgeeks.org › java › override-equalsobject-hashcode-method
Why to Override equals(Object) and hashCode() method ? - GeeksforGeeks
December 22, 2025 - Example: This program shows why overriding both equals() and hashCode() is necessary when using objects as HashMap keys. ... import java.util.*; class Geek { String name; int id; Geek(String name, int id) { this.name = name; this.id = id; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Geek geek = (Geek) obj; return name.equals(geek.name) && id == geek.id; } @Override public int hashCode() { return id; } } class GFG { public static void main(String[] args) { Geek g1 = new Geek("Ram", 1); Geek g2 = new Geek("Ram", 1); Map<Geek, String> map = new HashMap<>(); map.put(g1, "CSE"); map.put(g2, "IT"); for (Geek geek : map.keySet()) { System.out.println(map.get(geek)); } } }
🌐
Baeldung
baeldung.com › home › java › core java › java equals() and hashcode() contracts
Java equals() and hashCode() Contracts | Baeldung
January 8, 2024 - If we want to use instances of the Team class as HashMap keys, we have to override the hashCode() method so that it adheres to the contract; equal objects return the same hashCode.
🌐
JetBrains
jetbrains.com › guide › java › tips › generate-equals-hashcode
Generate Overrides for equals(), hashCode() and toString() - JetBrains Guide
February 17, 2023 - editing java · You can use ⌘N (macOS) / Alt+Insert (Windows/Linux) for the Generate menu and then select equals() and hashCode(). You can also use the same shortcut again and select toString() to override that method as well.
Top answer
1 of 7
8

should we always override the equals and hashCode even if we don’t intent at that point to use the class with any Collection classes?

No and I would go even further as to say you probably don't need to override them even if you are going to put them into a collection. The default implementations are perfectly compatible with collections as is. For lists, it's irrelevant anyway.

You should override equals if and only if your objects have a logical identity that is independent of their physical identity. In other words, if you want to have multiple objects that represent the same entity. Integer, is a good example of this. The integer 2 is always 2 regardless of whether there are 100 instances or 1 of the Integer object with the value of 2.

You must override hashcode if you've overridden equals.

That's it. There are no other good reasons to modify these.

As a side note, the use of equals to implement algorithms is highly overused. I would only do this if your object has a true logical identity. In most cases, whether two objects represent the same thing is highly context dependent and it's easier and better to use a property of the object explicitly and leave equals alone. There are many pitfalls to overriding equals, especially if you are using inheritance.

An example:

Let's say you have an online store and you are writing a component that fulfills orders. You decide to override the equals() method of the Order object to be based on the order number. As far as you know, that's the it's identity representation. You query a DB every so often and create objects from the response. You take each Order object and keep it as a key in a set which is all the orders in process. But there's a problem, orders can be modified in a certain time frame. You now might get a response from the DB that contains the same Order number but with different properties.

You can't just write this object to your set because you'll lose track of what was in process. You might end up processing the same order twice. So, what are the options? You could update the equals() method to include a version number or something additional. But now you have to go through your code to figure out where you need to base the logic on the having the same order number and where you need it to be based on the new object identity. In other words, there's not just one answer to whether two objects represent the same thing. In some contexts it's the order, and in some contexts it's the order and the version.

Instead of the set, you should build a map and use the order number as the key. Now you can check for the existence of the key in the map and retrieve the other object for comparison. This is much more straightforward and easy to understand than trying to make sense of when the equals method works they way you need it to for different needs.

A good example of this kind of complexity can be found in the BigDecimal class. You might think that BigDecimal("2.0") and BigDecimal("2.00") are equal. But they are not.

Conclusion:

It can make sense to implement equals() (make sure you update hashcode() too if you do) and doing so doesn't prevent the use of any of the techniques I describe here.

But if you are doing this:

  • Make sure your object is immutable
  • Use every meaningful property of the object to define equals.
  • If you are using inheritance, either:
    1. make equals final on the base class OR
    2. you must check that the actual type matches in subclasses

If any of these aren't followed, you are in for trouble.

2 of 7
4

In Java, if you don’t override anything, equality is defined as object references being equal, and the hash code is the bit pattern of the reference. That works just fine to put objects into containers.

And there are objects where this is exactly right. For example an object representing a window in the UI. Two windows are equal if and only if they are the same window.

PS. It makes absolutely sense to have a set of windows, or a dictionary with windows as keys, or an array of windows and lookup if the array contains some window - so you need to be able to compare windows for equality.

🌐
Mkyong
mkyong.com › home › java › java – how to override equals and hashcode
Java - How to override equals and hashCode - Mkyong.com
March 24, 2016 - public class User { private String ... : 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; } }...
🌐
InApp
inapp.com › home › if we override equals(), then we may or may not override hashcode(). (java override equals | java override hashcode)
If we override equals(), then we may or may not override hashcode(). (Java override equals | Java override hashcode) - InApp
May 24, 2023 - Compile and run this code and this will return the Hashcode Test · What is wrong with the 1st example? The two instances of HashCodeSample are logically equal according to the class’s equals method. Because the hashCode() method is not overridden, these two instances’ identities are not in common with the default hashCode implementation.
Find elsewhere
🌐
Blogger
javarevisited.blogspot.com › 2011 › 02 › how-to-write-equals-method-in-java.html
Overriding equals() and hashCode() method in Java and Hibernate
Just to add : 1) Two object which is logically equal but loaded from different ClassLoader can not be equals. 2) Use EqulasBuilder and HashCodeBuilder from Apache commons for overriding equals and hashCode. ... Anonymous said...
🌐
Crunchify
crunchify.com › java j2ee tutorials › java collections – hashcode() and equals() – how to override equals() and hashcode() method in java?
Java Collections - hashCode() and equals() - How to Override equals() and hashcode() Method in Java? • Crunchify
December 31, 2021 - @Override public boolean equals(Object ... { return true; } else { return false; } } @Override public int hashCode() { int result = 0; result = (int) (value / 11); return result; } } Test1: One and Two are equal Test2: Three and ...
🌐
How to do in Java
howtodoinjava.com › home › java basics › java hashcode() and equals() methods
Java hashCode() and equals() Methods - HowToDoInJava
February 23, 2023 - If both employee objects have been ... the second important method hashCode(). As java docs say, if we override equals() then we must override hashCode()....
🌐
Medium
lazy-programmer.medium.com › why-it-is-important-to-override-equals-and-hashcode-method-for-custom-objects-1d2bc629b5c4
Why it is Important to Override equals and hashcode method for Custom Objects? | by Amandeep Singh | Medium
June 20, 2023 - In this example, without overriding equals and hashCode, the set will consider person1 and person2 as distinct objects, even though their attributes are the same. As a result, the set will contain duplicate objects, violating the desired behavior. The equals and hashCode methods have contractual obligations defined in the Object class documentation. Failing to adhere to these obligations can lead to unexpected results when using objects in various Java ...
🌐
Blogger
javarevisited.blogspot.com › 2011 › 10 › override-hashcode-in-java-example.html
How to override hashcode in Java example - Tutorial
Java intends to provide equals ... to test equality and to provide a hash or digest based on the content of the class. The importance of hashcode increases when we use the object in different collection classes which works on hashing principle e.g. hashtable and hashmap. A well-written hashcode method can improve performance drastically by distributing objects uniformly and avoiding a collision. In this article, we will see how to correctly override the hashcode() method in java with a simple ...
🌐
Programming.Guide
programming.guide › java › overriding-hashcode-and-equals.html
Java: Why you should always override hashCode when overriding equals | Programming.Guide
@Override public boolean equals(Object o) { IntBox other = (IntBox) o; return this.i == other.i; } } class Main { public static void main(String[] args) { Set<IntBox> intBoxes = new HashSet<>(); intBoxes.add(new IntBox(0)); boolean found = intBoxes.contains(new IntBox(0)); // found == false } }
🌐
Coderanch
coderanch.com › t › 664010 › java › Override-hashcode-equals
Override only hashcode but not equals. (Java in General forum at Coderanch)
Let's take the following example: We haven't overridden equals(), so this means that two copies of a book with the same ISBN are different books. This also means that the book should always return the same hash code. However, if we take a copy of a book and change its ISBN, the book will still ...
🌐
Medium
medium.com › @pulapaphani › why-overriding-equals-and-hashcode-in-java-b5f869f985d2
Why : Overriding equals() and hashCode() in Java | by Phani Kumar | Medium
January 16, 2020 - As per the Java documentation, developers should override both methods in order to achieve a fully working equality mechanism — it’s not enough to just implement the equals() method. If two objects are equal according to the equals(Object) method, then calling the hashcode() method on each ...
🌐
Coderanch
coderanch.com › t › 548121 › java › Overriding-hashCode-equals
Overriding hashCode() and equals() (Java in General forum at Coderanch)
That depends on the implementation of class Book. With the following implementation they are not equal: You have to override equals (and therefore also hashCode) to specify what equality means. In your example you assumed that Book equality means ISBN equality, but you do have to implement ...
🌐
DZone
dzone.com › data engineering › data › working with hashcode() and equals()
Working With hashcode() and equals()
January 2, 2018 - HashSet stores its elements in memory buckets. Each bucket is linked to a particular hash code. When calling students.add(alex1), Java stores alex1 inside a bucket and links it to the value of alex1.hashcode().
🌐
Test-king
test-king.com › blog › common-pitfalls-and-best-practices-for-overriding-equals-and-hashcode-in-java
overriding equals and hashCode best practices
This ensures that objects that are logically equal will be placed in the same bucket when stored in a hash-based collection. Uniformity: The hashCode() method must always return the same value for an object as long as the object’s state does not change. Changing the object’s state should result in a change in the hash code. Overriding the hashCode() method typically involves computing a hash code based on the object’s important fields—those that define its equality.
🌐
Javapapers
javapapers.com › core-java › hashcode-and-equals-methods-override
hashCode And equals Methods Override - Javapapers
May be you should also go through String equals also at this juncture as String equality is one of the celebrated topic in Java. ... I think there’s a typo here. Shouldn’t it be this.color.equals(tiger.getColor()) and this.stripePattern.equals(tiger.getStripePattern()) ? ... Hi, I have 1 question, if equals method says two object are equal so if in any class I implement equals method and hashcode method to always return same value, will that class be singleton? Please confirm. ... Yes, exactly in the implementation example of overriding the Equals method.