Why HashMap Capacity is ALWAYS a Power of 2
π― The Questionβ
"In college textbooks, we calculate a hash table bucket index using
index = hash % capacity. Why does Java'sHashMapalways enforce a capacity that is a power of 2 (16, 32, 64, 128...), and how does it compute bucket indices without using the modulo operator?"
β‘ 30-Second Elevator Pitchβ
At the hardware CPU level, the Modulo operator (%) requires integer division (IDIV in x86):
- Integer division is one of the slowest mathematical operations a CPU can perform, taking 20 to 40 clock cycles.
- In high-throughput collections processing millions of
get()andput()calls per second, modulo arithmetic creates a severe CPU pipeline bottleneck.
The Power-of-2 Bitwise Optimization: When capacity is a power of 2 (), the mathematical modulo operation is 100% equivalent to a bitwise AND with :
A bitwise AND executes in a single CPU clock cycle (0.5 nanoseconds)βmaking index calculation up to faster.
π§ Under-the-Hood: Why the Bitmask Identity Worksβ
When is a power of 2, creates a binary mask of all 1s:
The bitwise AND simply extracts the lower bits of the hash code, which is mathematically identical to remainder division by .
π¬ The Danger of Non-Power-of-2 Sizesβ
If is not a power of 2, contains zero bits in between, permanently disabling certain bucket indices:
- Suppose (
1001in binary). - Any number
& 1001can only ever produce indices0, 1, 8, 9. - Buckets
2, 3, 4, 5, 6, 7will never receive an element, causing massive collision clustering and wasting 60% of array capacity!
π Comparison Matrix: Modulo (%) vs. Bitwise AND (&)β
| Metric / Aspect | Modulo Indexing (hash % n) | Bitwise Indexing (hash & (n - 1)) |
|---|---|---|
| CPU Instruction | IDIV (Integer Division) | AND (Bitwise AND) |
| Hardware Latency | π’ 20β40 CPU cycles | β‘ 1 CPU cycle (~0.5 ns) |
| Capacity Constraint | Any integer value | Strictly a power of 2 () |
| Bucket Utilization | Uniform (if hash is uniform) | Uniform only if |
| Real-World Runtimes | Educational implementations | Java HashMap, Go map, Python dict |
π‘ What Interviewers Ask Next (Follow-Up Traps)β
-
"What is the HashMap Perturbation (Hash Defense) function in Java?"
- Answer: Because
hash & (n - 1)only uses the lowest bits of the hash, if two objects have different high bits but identical lower bits, they will collide in the same bucket. Java fixes this by XORing the top 16 bits with the bottom 16 bits:This spreads high-bit entropy down to the lower bits, preventing collision storms.static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
- Answer: Because
-
"If a user initializes a HashMap with
new HashMap<>(10), what will its actual capacity be?"- Answer: It will be 16. Java's
tableSizeFor()method rounds any input integer up to the nearest power of 2 using bit-shifting (numberOfLeadingZeros).
- Answer: It will be 16. Java's
Interview Answer: HashMaps enforce power-of-2 capacities to replace expensive integer division (%, 20β40 CPU cycles) with bitwise AND (& (n - 1), 1 CPU cycle). The bitmask isolates the lower bits to calculate the array index in a single clock cycle without arithmetic overhead.