Foundation · Module 5 · Lesson 1
Hash-table internals
Buckets, hash functions, collisions, load factor, and resizing.
Lesson 27 of 123
1d streakInteractive Visualization
See how hash-table internals works
Change the inputs, run an operation, and connect each visible state change to the explanation below.
Interactive data structure
Change the structure and watch the operation
Try an operation and connect the visible movement to its runtime cost.
How Hash Tables Work: Buckets, Collisions & Rehashing
A Hash Table maps arbitrary keys (strings, objects, numbers) to array indices using a Hash Function. It provides average O(1) time complexity for insertions, lookups, and deletions by transforming a key into an integer bucket index.
Key -> hash(key) -> index = hash & (capacity - 1)
Bucket Array (Array of Node pointers):
[ 0 ] -> null
[ 1 ] -> [ Key: "apple" | Val: $1.20 ] -> [ Key: "melon" | Val: $3.50 ] -> null (Collision Chain)
[ 2 ] -> [ Key: "orange" | Val: $0.80 ] -> null
[ 3 ] -> null
[ 4 ] -> [ Key: "banana" | Val: $0.50 ] -> null
Collision Resolution Strategies:
1. Separate Chaining: Each bucket holds a linked list (or balanced Red-Black tree when length >= 8 in Java).
2. Open Addressing (Linear Probing): On collision at slot i, probe i+1, i+2, etc., until an empty slot is found.| Metric / Property | HashMap (Separate Chaining) | Open Addressing (Linear Probing) |
|---|---|---|
| Collision Handling | Appends node to linked list or tree at bucket | Searches forward for the next empty array slot |
| Deletion Cost | Trivial: unlink node from chain | Requires tombstone marker to avoid breaking search chains |
| Max Load Factor | Can exceed 1.0 (typical threshold 0.75) | Must stay well below 1.0 (typically 0.5 - 0.7) |
| Cache Performance | Pointer chasing across heap nodes | Excellent cache locality (contiguous array probing) |
Load Factor and Dynamic Rehashing Cost
size / capacity. When size > capacity * 0.75, the hash table allocates an array of double the capacity and re-hashes every element. Like dynamic arrays, while one rehash costs $O(n)$, amortized lookup and insertion remain strictly O(1).Interview Trap: Mutable Object Keys
hashCode(), the object’s bucket index changes. When you subsequently call map.get(key), the map searches the wrong bucket and fails to find the entry, causing a severe memory leak.Cost Model
Complexity & Trade-offs
When to use it
- Presence, uniqueness, frequency, complement, and previously seen state queries.
- Replacing repeated scans with indexed history.
- Grouping values by a canonical key.
Common mistakes
- Assuming hash lookup has a deterministic O(1) worst case.
- Updating the map before a query that requires a distinct earlier item.
- Using mutable or inconsistent keys.
Practice prompts
- Reproduce the worked Hash-table internals example without looking at the trace.
- Change one input condition and explain whether the Hash-table internals invariant still holds.
- Implement the approach, derive its cost, and compare it with a straightforward baseline.
Mastery check