Intuition
A coat check doesn’t search every hook for your coat. It gives you a ticket number and hangs the coat on that hook, so getting it back is one step. A hash map does the same: a hash function turns each key into a number, and that number picks the slot, called a bucket, where the value goes.
Two keys can get the same bucket. That’s a collision, and the map has to cope with it. The figure uses chaining: each bucket holds a short list of the keys that landed there.
How it works
- Hash the key to a number. The figure adds up the character codes: “fig” is 102 + 105 + 103 = 310.
- Pick a bucket with the remainder: 310 % 8 = 6.
- Put: walk that bucket’s chain. If the key is there, replace its value; otherwise add it to the chain.
- Get: hash the key the same way and search only that bucket’s chain.
The load factor is keys ÷ buckets. When it gets too high, chains grow and lookups slow down, so real maps resize: they allocate more buckets (often double) and re-insert every key. Like a dynamic array, that rare O(n) step keeps the average cost O(1).
Complexity
| Operation | Average | Worst |
|---|---|---|
| Get | O(1) | O(n) |
| Put | O(1) | O(n) |
| Delete | O(1) | O(n) |
The worst case happens when many keys share a bucket: with a bad hash function, or with keys chosen by an attacker. Many languages randomize their hash seeds to make that hard.
Common mistakes
- Mutable keys. Changing a key after storing it changes its hash, so the map looks in the wrong bucket and can’t find it.
- Relying on order. Iteration order is not sorted, and in some languages not even stable. Python dicts and JavaScript
Mapkeep insertion order; Go deliberately randomizes it. - Custom keys with
equalsbut no matching hash. In Java, two equal objects must have the samehashCode(), or lookups fail.
In other languages
| Language | Type | On a collision |
|---|---|---|
| Python | dict |
Open addressing: probe other slots |
| JavaScript | Map |
Engine-specific |
| Java | HashMap |
Chaining; long chains become small trees |
| Go | map |
Open addressing (Swiss tables, since Go 1.24) |
| Rust | HashMap |
Open addressing (Swiss tables) |
| C | None built in | Your choice |
Check yourself
Check yourself
With the figure's hash, which of 8 buckets does "fig" go in?
Its character codes add up to 102 + 105 + 103 = 310, and 310 % 8 = 6.
Check yourself
Two different keys land in the same bucket. What is that called?
A collision. Chaining stores both keys in that bucket’s list; open addressing moves the second key to another free slot.
Sources
- Cormen, Leiserson, Rivest and Stein, Introduction to Algorithms, chapter 11, “Hash Tables” (3rd edition).
- CPython source,
Objects/dictobject.c: the comments at the top describe howdictprobes for a free slot.
Finished this page?
Your list