public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
繼承 AbstractMap,實現 Map、Cloneable、Serializable。非線程安全,可用 Collections.synchronizedMap() 包裝。
底層維護一個 Entry<K,V>[] table 數組,每個槽位是單向鏈表頭節點。鍵的 hashCode() 經擾動函數計算 hash 值,再透過 indexFor(hash, length) 定位索引。Hash 碰撞時掛載至鏈表。

static class Entry<K,V> implements Map.Entry<K,V> {
final K key; V value; Entry<K,V> next; int hash;
Entry(int h, K k, V v, Entry<K,V> n) { ... }
// getKey, getValue, setValue, equals, hashCode, toString...
}
next 指向下一節點,形成鏈表。新增節點時採用頭插法:table[i] = new Entry(hash, key, value, oldEntry),最新節點始終位於鏈表頭。
為何容量必須是 2 的冪? indexFor 使用 h & (length - 1) 代替取模運算。若 length 為 2 的冪,length-1 低位全為 1,& 運算等同於取模且效率極高;同時保證索引分布均勻(奇數索引也會被使用),避免浪費一半空間。
構造方法僅記錄參數,真正初始化 table 發生在首次 put 時(inflateTable(threshold))。此時將初始容量調整為最近的 2 的冪,重新計算 threshold,分配數組。
inflateTable 初始化。putForNullKey,固定存放 table[0]。hash(key) 經擾動函數(高位參與運算)降低碰撞。indexFor(hash, table.length) 獲取索引。== 或 equals()),替換 value 並返回舊值。addEntry 頭插新節點,size++,檢查是否需擴容(size >= threshold 且槽位非空)。table[0] 鏈表。hash 與 key,命中返回 value,否則返回 null。remove(key):定位節點,從鏈表移除,size--,返回被刪除值。keySet() / values() / entrySet():返回視圖集合,底層迭代器遍歷 table 及鏈表。containsKey/Value:同上邏輯查找。