How Does HashMap Work Internally in Java?
Understand how Java HashMap works internally: hashing, buckets, collisions, treeification, load factor and resizing, with code examples and interview questions.
Expected Interview Answer
A HashMap stores key-value pairs in an array of buckets, using the key's hashCode (spread by an internal hash function) to compute a bucket index, and equals to resolve which entry within a bucket matches a given key.
Each bucket holds a chain of Node entries; when two keys map to the same index (a collision) they are stored in the same bucket as a linked list. Since Java 8, once a bucket exceeds a threshold of eight nodes and the table is large enough, that bucket is converted into a balanced red-black tree to bound worst-case lookups at O(log n) instead of O(n). When the number of entries exceeds capacity times the load factor (default 0.75), the map resizes by doubling capacity and rehashing entries. Average get and put are O(1) thanks to good hash distribution.
- Average O(1) put and get with a good hash function
- Treeification bounds worst-case bucket lookups at O(log n)
- Automatic resizing keeps buckets short
- Allows one null key and multiple null values
- Flexible general-purpose key-value storage
AI Mentor Explanation
A HashMap is like assigning each player to a locker by hashing their jersey number. Most lockers hold one player, so you find anyone instantly. When several numbers hash to the same locker, they share it as a small list you scan; if that list grows too long, the ground staff reorganize it into a sorted shelf so lookups stay quick.
Step-by-Step Explanation
Step 1
Compute the hash
HashMap calls the key's hashCode and spreads the bits with an internal hash function to reduce collisions.
Step 2
Find the bucket
It maps the spread hash to an index using (n - 1) & hash, where n is the table length (a power of two).
Step 3
Handle collisions
Entries landing in the same bucket form a chain; put uses equals to detect and overwrite a matching key.
Step 4
Treeify long buckets
Since Java 8, a bucket with more than 8 nodes (in a table of at least 64) becomes a red-black tree for O(log n) lookups.
Step 5
Resize when full
When size exceeds capacity times load factor (0.75), capacity doubles and entries are rehashed into the larger table.
What Interviewer Expects
- Understanding of hashCode and equals working together
- Knowledge of bucket indexing with (n - 1) & hash
- Explanation of collision handling via chaining
- Awareness of Java 8 treeification at threshold 8
- Understanding of load factor, capacity, and resizing
Common Mistakes
- Saying HashMap uses only hashCode and never equals
- Believing get is always O(1) even with bad hashing
- Not knowing about treeification introduced in Java 8
- Confusing load factor with capacity
- Overriding hashCode but not equals (or vice versa)
Best Answer (HR Friendly)
“A HashMap stores data as key-value pairs and uses a mathematical fingerprint of the key to decide where to place it, so lookups are usually instant. If several keys land in the same spot it keeps them together and reorganizes when things get crowded to stay fast.”
Code Example
import java.util.*;
public class HashMapInternals {
static class Point {
final int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
// Both must be overridden together for HashMap to work correctly
@Override public int hashCode() { return Objects.hash(x, y); }
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point)) return false;
Point p = (Point) o;
return x == p.x && y == p.y;
}
}
public static void main(String[] args) {
Map<Point, String> map = new HashMap<>();
map.put(new Point(1, 2), "A");
// Same field values -> same hashCode and equals -> found
System.out.println(map.get(new Point(1, 2))); // A
System.out.println(map.containsKey(new Point(3, 4))); // false
}
}Follow-up Questions
- What happens when two keys have the same hashCode but are not equal?
- How and when does a HashMap resize?
- What changed in HashMap between Java 7 and Java 8?
- Why must you override equals and hashCode together?
- How does HashMap differ from ConcurrentHashMap and Hashtable?
MCQ Practice
1. In Java 8+, a bucket is converted to a red-black tree when it exceeds how many nodes?
A bucket with more than 8 nodes (in a table of at least 64) is treeified for O(log n) lookups.
2. What is the default load factor of a HashMap?
The default load factor is 0.75, balancing space usage against collision frequency before resizing.
3. Which pair of methods must be consistent for correct HashMap keys?
hashCode decides the bucket and equals confirms the match, so both must be overridden consistently.
Flash Cards
How does HashMap pick a bucket? — It spreads the key's hashCode, then computes (n - 1) & hash where n is the table length.
What is treeification? — Converting a long bucket (>8 nodes, table >=64) into a red-black tree for O(log n) lookups, added in Java 8.
Default capacity and load factor? — Initial capacity 16 and load factor 0.75; resize (double) when size exceeds capacity * load factor.
Why override hashCode and equals together? — hashCode locates the bucket and equals verifies the key; inconsistency causes lost or duplicated entries.