Short answer
A HashMap holds an array of buckets; the key's hashCode is spread (to mix high bits) and masked to an index, and collisions chain in that bucket.
Explanation
When size exceeds capacity times the load factor (default 0.75), it resizes to double capacity and rehashes. Since Java 8, a bucket with many collisions (8+) and sufficient table size converts its linked list to a red-black tree, improving worst-case lookup from O(n) to O(log n) — a mitigation against hash-collision DoS — and untreeifies on shrink.
Common mistakes
- Saying HashMap uses a tree for every bucket — it treeifies only buckets with many collisions (8+) when the table is large enough.
- Forgetting that resizing doubles the table and rehashes entries.