How does a HashMap work internally in Java, from the moment you call put to the moment you call get?
A HashMap is an array of buckets, each bucket holding a linked list of entries. The key steps are these.
Hashing. The key's hashCode is computed, and the JVM applies a spread function to it — an xor-and-shift that mixes the high bits down, so that keys whose hash codes differ only in their upper bits still land in different buckets.
Index. The spread hash is masked with the table length minus one to produce an index into the table array. Because the table length is always a power of two, that mask is equivalent to a modulo, and it is fast.
Bucket lookup. The map walks the entries in that bucket, comparing each entry's hash first and then calling equals on the key. If a match is found, the value is replaced; otherwise the new entry is appended to the bucket's list.
Resizing. When the number of entries exceeds the load factor — 0.75 by default — the table doubles and the entries are redistributed. Because the index is derived from the hash and the table length, each entry goes to either its old index or that index plus the old length, which makes the resize linear rather than requiring every entry to be rehashed from scratch.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("two", 2);
map.put("one", 11); // replaces the value, does not add an entry
System.out.println("size : " + map.size());
System.out.println("get one : " + map.get("one"));
System.out.println("get two : " + map.get("two"));
System.out.println("get three : " + map.get("three"));
// The hash code decides the bucket.
System.out.println("hash one : " + "one".hashCode());
System.out.println("containsKey: " + map.containsKey("two"));
// Iteration order is not guaranteed and may change after a resize.
System.out.println("entries : " + map.entrySet());
}
}The output confirms the observable behaviour: the map holds two entries because putting the same key twice replaced the value, a missing key returns null, and iteration order is not sorted or insertion-ordered.
Two implementation details that come up in interviews. The map uses a lazy resize — the table is resized when the next write happens, not eagerly — and the tree is stored as an array of Node objects with an explicit hash field, which removed the need to recompute the hash when moving an entry during a resize.