EnumMap
Efficient enum-keyed maps.
EnumMap is a free Java Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is EnumMap?
EnumMap is a specialized Map whose keys are constants of a single enum type.
Internally it is backed by a plain array indexed by the constant's ordinal. This makes lookups and inserts extremely fast with no hashing.
import java.util.EnumMap;
import java.util.Map;
public class Main {
enum Day { MON, TUE, WED }
public static void main(String[] args) {
Map<Day, String> plan = new EnumMap<>(Day.class);
plan.put(Day.MON, "Gym");
plan.put(Day.WED, "Swim");
System.out.println(plan);
}
}Construction Needs the Class
An EnumMap must know the key type up front, so the constructor takes the Class object: new EnumMap<>(Day.class).
This is how it sizes its internal array to the number of constants.
import java.util.EnumMap;
public class Main {
enum Priority { LOW, MEDIUM, HIGH }
public static void main(String[] args) {
EnumMap<Priority, Integer> counts = new EnumMap<>(Priority.class);
counts.put(Priority.HIGH, 5);
System.out.println(counts.get(Priority.HIGH));
}
}Array-Backed Speed
Because keys are stored at array[ordinal], get and put are direct array accesses, faster than HashMap's hashing and bucket walk.
There is no boxing of the key and no hashCode call.
import java.util.EnumMap;
public class Main {
enum Slot { A, B, C, D }
public static void main(String[] args) {
EnumMap<Slot, Integer> m = new EnumMap<>(Slot.class);
for (Slot s : Slot.values()) m.put(s, s.ordinal() * 10);
System.out.println(m.get(Slot.C));
}
}Iteration in Key Order
EnumMap iterates entries in the natural order of the keys, which is their declaration order.
This gives stable, predictable output, unlike HashMap.
import java.util.EnumMap;
import java.util.Map;
public class Main {
enum Phase { PLAN, BUILD, SHIP }
public static void main(String[] args) {
Map<Phase, Integer> hours = new EnumMap<>(Phase.class);
hours.put(Phase.SHIP, 3);
hours.put(Phase.PLAN, 8);
hours.put(Phase.BUILD, 20);
for (Map.Entry<Phase, Integer> e : hours.entrySet()) {
System.out.println(e.getKey() + " = " + e.getValue());
}
}
}Null Keys Are Forbidden
EnumMap does not allow null keys; a null key throws NullPointerException.
Null values are allowed, just like other maps.
import java.util.EnumMap;
public class Main {
enum K { A, B }
public static void main(String[] args) {
EnumMap<K, String> m = new EnumMap<>(K.class);
m.put(K.A, null); // null value is fine
System.out.println("A -> " + m.get(K.A));
System.out.println("contains A: " + m.containsKey(K.A));
}
}Grouping With EnumMap
A common use is counting or grouping by an enum category. merge makes tallying concise.
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
public class Main {
enum Type { FRUIT, VEG, MEAT }
record Item(String name, Type type) {}
public static void main(String[] args) {
List<Item> items = List.of(new Item("apple", Type.FRUIT), new Item("pear", Type.FRUIT), new Item("beef", Type.MEAT));
Map<Type, Integer> counts = new EnumMap<>(Type.class);
for (Item i : items) counts.merge(i.type(), 1, Integer::sum);
System.out.println(counts);
}
}getOrDefault and computeIfAbsent
All standard Map default methods work. getOrDefault avoids null checks, and computeIfAbsent lazily builds values.
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
public class Main {
enum Group { A, B }
public static void main(String[] args) {
Map<Group, List<String>> m = new EnumMap<>(Group.class);
m.computeIfAbsent(Group.A, k -> new ArrayList<>()).add("first");
System.out.println(m);
System.out.println(m.getOrDefault(Group.B, List.of()));
}
}Copy Constructor
EnumMap has a copy constructor that accepts another Map. If the source is an EnumMap, the key type is inferred from it.
import java.util.EnumMap;
import java.util.Map;
public class Main {
enum K { X, Y }
public static void main(String[] args) {
EnumMap<K, Integer> a = new EnumMap<>(K.class);
a.put(K.X, 1);
EnumMap<K, Integer> b = new EnumMap<>(a);
b.put(K.Y, 2);
System.out.println("copy: " + b);
}
}EnumMap vs ordinal Arrays
Before EnumMap, people used raw arrays indexed by ordinal(). That is fragile and unsafe.
EnumMap gives the same array speed with type safety, bounds safety, and a clean Map API.
import java.util.EnumMap;
import java.util.Map;
public class Main {
enum Season { SPRING, SUMMER, FALL, WINTER }
public static void main(String[] args) {
Map<Season, String> mood = new EnumMap<>(Season.class);
mood.put(Season.SUMMER, "sunny");
// Safer and clearer than String[] indexed by ordinal
System.out.println(mood.get(Season.SUMMER));
}
}Nested EnumMaps
You can nest EnumMaps to model a matrix keyed by two enums, such as a state transition table.
import java.util.EnumMap;
import java.util.Map;
public class Main {
enum State { SOLID, LIQUID, GAS }
enum Transition { MELT, FREEZE }
public static void main(String[] args) {
Map<State, Map<Transition, State>> table = new EnumMap<>(State.class);
Map<Transition, State> solid = new EnumMap<>(Transition.class);
solid.put(Transition.MELT, State.LIQUID);
table.put(State.SOLID, solid);
System.out.println(table.get(State.SOLID).get(Transition.MELT));
}
}Choosing the Right Type
Rule of thumb:
- Keys are enum constants and you want a map: use EnumMap.
- You want a set of enums: use EnumSet.
- Keys are arbitrary objects: use HashMap.
import java.util.EnumMap;
import java.util.Map;
public class Main {
enum Level { DEBUG, INFO, WARN, ERROR }
public static void main(String[] args) {
Map<Level, Integer> thresholds = new EnumMap<>(Level.class);
for (Level l : Level.values()) thresholds.put(l, l.ordinal() * 100);
System.out.println(thresholds);
}
}Quick Check
Test your EnumMap knowledge.
Recap
You learned EnumMap:
- An array-backed Map keyed by enum constants.
- Constructor takes the key Class; no null keys allowed.
- Iterates in declaration order.
- The safe, fast replacement for ordinal-indexed arrays.
You have completed the advanced enums course.
import java.util.EnumMap;
public class Main {
enum K { A }
public static void main(String[] args) {
EnumMap<K, String> m = new EnumMap<>(K.class);
m.put(K.A, "done");
System.out.println("EnumMap course complete: " + m.get(K.A));
}
}Frequently asked questions
Is the “EnumMap” lesson free?
Yes — the full text of “EnumMap” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “EnumMap”?
Efficient enum-keyed maps. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “EnumMap” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.