Fundamentals 7 min read

Why and How to Override hashCode() and equals() in Java

This article explains why Java developers must override both hashCode() and equals() methods for proper object comparison in hash-based collections, outlines the scenarios requiring such overrides, and provides detailed example code demonstrating correct implementations.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Why and How to Override hashCode() and equals() in Java

When interviewing for a Java software development position, a common question is why one should override hashCode() and equals() in a JavaBean. The default Object.equals() compares memory addresses, not field values, so custom equality logic is often needed.

Why override? In business logic, objects may be considered equal based on their attributes rather than identity. Overriding equals() allows this, but to work correctly with hash‑based collections (e.g., HashSet , HashMap ), hashCode() must also be overridden to satisfy the contract:

If two objects are equal according to equals() , they must return the same hashCode() value.

If two objects are not equal, their hash codes should, ideally, differ.

The Object.equals() source simply returns this == obj :

public boolean equals(Object obj) {
    return (this == obj);
}

HashSet uses hashCode() to locate a bucket; if a collision occurs, it falls back to equals() to decide whether to store the new element. Failing to override both can lead to duplicate entries or performance degradation.

When to override? Whenever a custom class is stored in a hash‑based collection and logical equality based on its fields is required.

public class Student {
    private String name;
    private Integer age;
    // constructors, getters, setters omitted for brevity
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 17;
        result = prime * result + name.hashCode();
        result = prime * result + age;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Student other = (Student) obj;
        if (!name.equals(other.name)) return false;
        if (!age.equals(other.age)) return false;
        return true;
    }
}

Demo with HashSet shows that two Student objects with identical fields are considered equal and only one is kept:

public class Demo {
    public static void main(String[] args) {
        Student stu1 = new Student("awu", 22);
        Student stu2 = new Student("awu", 22);
        Student stu3 = new Student("awu", 33);
        Set set = new HashSet();
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        System.out.println(set.size()); // prints 2
    }
}

If the collection is not hash‑based (e.g., ArrayList ), overriding hashCode() has no effect on containment checks, as demonstrated by a list example that retains all three objects.

In summary, correctly overriding hashCode() and equals() ensures logical equality works with hash‑based collections, prevents duplicate entries, and maintains expected performance.

JavaprogrammingCollectionsHashSetequalsHashCodeobject
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.