
A hash map (also called a dictionary, hash table, or associative array) is a way to store facts so you can find them again almost instantly.
This is one of the most common data structures in programming, so nearly every language has its own name for it. If you've used any of these, you've used a hash map:
| Language | What it's called |
|---|---|
| Python | dict |
| JavaScript | Object or Map |
| Java | HashMap |
| C++ | unordered_map |
| C# | Dictionary |
| Ruby | Hash |
| Go | map |
Different name, same contract: store a key, get back a value, and do it fast.
Example Javascript Object:
{ apple: "macintosh", banana: "applebanana" }
If your data lives in a list, answering a simple question — Have I already seen this value? What index was it at? How many times did it appear? — usually means walking the list from the start. That works for a handful of items. It falls apart when the list is long and you ask the same kind of question over and over. Every ask can cost another full walk.
A hash map changes the contract. Instead of "search the collection," you say "look up this key." The key is the thing you will ask about again — a word, an ID, a number you have already processed. Attached to that key is a value: whatever you need to remember about it (an index, a count, a leftover amount, a pointer to more data).
This is the part that makes the speed possible, so it's worth slowing down on.
When you store a key, the hash map runs it through a hash function — a formula that converts the key into a number. That number is called a hash. Critically, the function is deterministic: the same key always produces the same number, every time you run it.
A rough mental model: take each character in the key, convert it to a numeric code, combine those numbers with some math (multiply, add, shift), then squeeze the result down to fit the size of the table — often with % table_size (the remainder after division). So something like:
hash("peach") → some large number → % 100 → 42
That final number, 42, is a slot index in an underlying array. So:
peach → "georgiapeach": compute hash("peach") → 42 → put "georgiapeach" in slot 42.peach later: compute hash("peach") again → same formula, same input → 42 again → go straight to slot 42 → the value is right there.No comparison against other keys happens at all. The hash map isn't searching for "peach" among everything it holds — it's recomputing the same address it used the first time and walking straight there. That's the entire trick: the key is not a label to search for, it's a formula that computes a location.
This is why a hash map lookup takes roughly the same effort whether the map holds 10 items or 10 million — you're not comparing against the others, you're computing one address and jumping to it.
(One wrinkle: two different keys can occasionally hash to the same slot — a "collision." Hash maps handle this with strategies like storing a small list at that slot, or moving to the next open one. As long as collisions are rare, which a good hash function ensures, this doesn't meaningfully slow things down.)
Hash maps are the standard tool whenever the bottleneck is repeated membership or retrieval:
target − x; is it already here?")The cost of that speed is memory. You keep a table large enough to hold the keys you care about. In exchange, typical lookups stay roughly the same effort as the data set grows — you're not paying "walk the whole list" on every question. When people say a hash map gives average O(1) lookup, they mean exactly that: one hop to the right place, not a search that grows with every new item.
O(1) is a nerdy way of saying: "the work doesn't really grow when the pile gets bigger."
Picture a vinyl shop. The slow way to find Miles Davis is flipping every sleeve and reading artist names. The fast way turns the name into a number with a hash, then opens the one bin that number points to — whether the shop holds 10 records or 10,000.
That filing system is the hash map idea again: text → number → address. You spend some space up front building the bins so you never have to dig through the whole stack later.
The skill to build: recognizing when a problem is really "I will need this fact again," and storing it the first time you see it so you never have to hunt for it twice..
Vinyl shop: artist name → hash → bin
A hash map turns text into a number, then uses that number as an address. Same artist name always hashes to the same place — so you jump to one bin instead of scanning the pile.
Toy hash (live)
hash("Miles Davis")
char codes: M→77 + i→105 + l→108 + e→101 + s→115 + ' '→32 + D→68 + a→97, …
→ 2173862561 · 2173862561 % 8 → bin B
How should we search?
Fast way: turn the artist name into a number (hash), then open that bin.
Try the slow way on a full shop, then the fast way. Flipping grows with the pile; hashing the name and opening one bin stays about the same — average O(1).
Messy stack (artist / album)
Bins (filed by hash of artist name)
For each number, ask whether target − x already sits in the map. If yes, return both indices; if not, record x → index and continue. One pass replaces the O(n²) double loop.
You need fast membership, frequency counts, or complements — and a nested scan is the naive first draft.