What is EnumMap, how is it implemented, and why is it preferred over HashMap for enum keys?
answer
- Array indexed by ordinal() -> no hashing
- Keys = one enum type, fixed at construction
- Iteration in enum declaration order
- No null keys (NPE), null values OK
- Faster + smaller than HashMap for enum keys
basics
~20 sEnumMap is a special map whose keys must be values of one enum type. Internally it's just an array indexed by each enum's position, so it's very fast and compact, and it keeps entries in the enum's declared order.
solid answer
~40 sEnumMap is a high-performance Map implementation specialized for keys from a single enum type, declared as new EnumMap<>(MyEnum.class). Internally it is backed by a plain array sized to the number of enum constants, indexed by each key's ordinal() (its position in the enum declaration). That means no hashing, no collisions, and no boxing of the index — lookups and inserts are direct array accesses, much faster and more memory-compact than a HashMap. Iteration order is the natural (declaration) order of the enum constants, which is deterministic. It rejects null keys (NullPointerException) but allows null values. It is not thread-safe. You should prefer EnumMap over HashMap whenever your keys are enum constants: it's faster, smaller, and gives predictable ordering. The only constraint is all keys must belong to the same enum type fixed at construction.
code
java · 14 linesenum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
EnumMap<Day, String> plan = new EnumMap<>(Day.class);
plan.put(Day.WED, "gym");
plan.put(Day.MON, "meeting");
// Iteration is in declaration order, not insertion order:
for (var e : plan.entrySet()) {
System.out.println(e.getKey() + " -> " + e.getValue());
}
// prints MON -> meeting, then WED -> gym
// plan.put(null, "x"); // throws NullPointerException (null key)
plan.put(Day.FRI, null); // null VALUE is allowedgo deeper
Knows EnumMap is a map for enum keys and is more efficient than HashMap there.
Explains the ordinal-indexed array implementation, declaration-order iteration, null-key rejection, and that it should be preferred for enum keys.
Discusses the no-hash/no-collision performance and memory wins, the single-enum-type constraint fixed at construction, null-value sentinel handling, and thread-safety.
Reasons about when ordinal-indexing assumptions matter (enum evolution, ordinal stability), EnumMap/EnumSet as performance idioms, and API design favoring enum-keyed structures over string-keyed maps.
## What an enum is An **enum** (enumerated type) is a class with a fixed, known set of named constant instances, e.g.: ``` enum Day { MON, TUE, WED, THU, FRI, SAT, SUN } ``` Each constant has an **ordinal**: its zero-based position in the declaration. `Day.MON.ordinal()` is `0`, `Day.TUE.ordinal()` is `1`, and so on. Crucially, the JVM knows *exactly how many* constants an enum has and that the set never changes at runtime. ## The problem EnumMap solves If you use a `HashMap<Day, X>`, the map must hash each key, find a bucket, handle collisions, and box things — general machinery that ignores the fact that enum keys are a small, fixed, densely-numbered set. That's wasteful when you already know each key maps cleanly to an index `0..n-1`. ## How EnumMap works internally `EnumMap` is **array-backed**. When you write `new EnumMap<>(Day.class)`, it: 1. Asks the enum class for its constants and allocates a **plain `Object[]` of exactly that length** (7 for `Day`). 2. To `put(key, value)`, it stores `value` at `array[key.ordinal()]`. To `get(key)`, it reads `array[key.ordinal()]`. So every operation is a **direct array index** — **no hashing, no collisions, no bucket chains, no boxing of the index**. This makes it: - **Faster** than `HashMap` (array access vs hash+equals). - **More memory-compact** (one small array vs bucket arrays + Entry node objects). - **Deterministically ordered**: iteration follows the **enum's declaration order** (ascending ordinal), always — unlike `HashMap`'s arbitrary order. A sentinel is used to distinguish "slot holds a real null value" from "slot is empty," which is why it can store null **values** while still tracking presence. ## Rules and limits - **Keys must all be from the same enum type**, fixed when you construct it (you pass the `Class` object). You can't mix enum types. - **Null keys are forbidden** (`NullPointerException`); **null values are allowed**. - **Not thread-safe** — wrap with `Collections.synchronizedMap` if shared. - It implements `Map`, so it's a drop-in for the interface. ## When to use it **Whenever your map's keys are constants of a single enum, prefer `EnumMap` over `HashMap`.** It is faster, smaller, and gives stable ordering. Typical uses: state-machine transition tables, per-enum configuration/counters, mapping enum to handlers. ## Comparison cheat-sheet | | EnumMap | HashMap | |---|---|---| | Key type | one enum type only | any | | Internals | array indexed by ordinal | hash buckets | | Speed | faster (direct index) | hashing overhead | | Memory | compact array | buckets + nodes | | Iteration order | enum declaration order | unspecified | | Null key | no (NPE) | one allowed | | Null value | yes | yes | ## One-line summary EnumMap = "a Map that is secretly an array indexed by `ordinal()`" — the right choice for enum keys: fast, compact, ordered.
- Why is EnumMap faster and more memory-efficient than HashMap for enum keys?It stores values in a plain array indexed by the key's ordinal(), so every get/put is a direct array access with no hashing, no collision handling, and no per-entry node objects. HashMap must hash keys, walk buckets, and allocate Entry nodes.
- What ordering does EnumMap iterate in, and can null be used as a key or value?It iterates in the enum's natural (declaration / ascending ordinal) order, deterministically. Null keys are rejected with NullPointerException; null values are allowed.
HashMap is a coat-check that computes a locker number for each coat. EnumMap is a fixed row of numbered lockers, one per enum constant — you walk straight to your locker, no lookup desk needed.
saying these in an interview costs you the question
- Claiming EnumMap uses hashing — it's array-indexed by ordinal.
- Saying iteration order is insertion or arbitrary — it's enum declaration order.
- Thinking it allows null keys (it throws NPE on null keys).
- Assuming it's thread-safe.
- Believing you can mix multiple enum types as keys in one EnumMap.