Backend Development 9 min read

Understanding HashMap: Why Overriding hashCode and equals Is Essential

This article explains how HashMap stores data using hash functions, illustrates hash collisions and chain addressing, and demonstrates why overriding hashCode and equals in custom key classes is essential for correct retrieval, using Java code examples and interview insights.

Architecture Digest
Architecture Digest
Architecture Digest
Understanding HashMap: Why Overriding hashCode and equals Is Essential

When interviewing junior Java developers, a common question is whether they have ever overridden the hashCode method, followed by a check on their experience using custom objects as keys in a HashMap . The author uses this scenario to introduce the underlying principles of hash tables.

First, the article reviews the basic data‑structure concept of a hash table: a simple hash function (e.g., x*x%5 ) maps values to indices in an array, turning an average linear search of O(n) into near‑constant time O(1). Simple examples show how numbers 6 and 7 are placed at indices 1 and 4 respectively.

The discussion then moves to hash collisions. When two different keys produce the same hash value, Java’s HashMap resolves the conflict with chaining (linked lists) at the colliding bucket, as illustrated by accompanying diagrams.

Crucially, the article explains why custom key classes must override both equals and hashCode . A complete Java example ( WithoutHashCode.java ) is provided, with the relevant code shown below:

1   import java.util.HashMap;
2   class Key {
3       private Integer id;
4       public Integer getId() { return id; }
5       public Key(Integer id) { this.id = id; }
6       // intentionally comment out equals and hashCode
7       // public boolean equals(Object o) {
8       //     if (o == null || !(o instanceof Key)) { return false; }
9       //     return this.getId().equals(((Key) o).getId());
10      // }
11      // public int hashCode() { return id.hashCode(); }
12   }
13   public class WithoutHashCode {
14       public static void main(String[] args) {
15           Key k1 = new Key(1);
16           Key k2 = new Key(1);
17           HashMap
hm = new HashMap<>();
18           hm.put(k1, "Key with id is 1");
19           System.out.println(hm.get(k2)); // prints null
20       }
21   }

Because Key does not define its own hashCode , the default implementation from Object returns the object's memory address, causing k1 and k2 to have different hash values and thus be placed in different buckets. Even after fixing the hash code (so both keys hash to the same bucket), the lack of an overridden equals means the map still cannot recognize the two keys as equal, resulting in a null lookup.

The article concludes by urging developers to always override both equals and hashCode when using custom objects as keys in a HashMap , ensuring correct behavior in real‑world projects and interview scenarios.

backendJavaInterviewHashMapdata structuresequalsHashCode
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.