How to Loop Through an Enum in Java
The Challenge
Iterate through all constants in an enumeration!
Example Enum
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}Solutions
Method 1: Using For-Each Loop
for (Day day : Day.values()) {
System.out.println(day);
}
// Output:
// MONDAY
// TUESDAY
// WEDNESDAY
// THURSDAY
// FRIDAY
// SATURDAY
// SUNDAYMethod 2: Using Traditional For Loop
Day[] days = Day.values();
for (int i = 0; i < days.length; i++) {
System.out.println(days[i]);
}Method 3: Using Arrays.stream()
import java.util.Arrays;
Arrays.stream(Day.values()).forEach(System.out::println);Method 4: Using EnumSet
import java.util.EnumSet;
EnumSet<Day> allDays = EnumSet.allOf(Day.class);
for (Day day : allDays) {
System.out.println(day);
}Advanced: Enum with Fields
enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6);
private final double mass;
private final double radius;
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double getMass() { return mass; }
public double getRadius() { return radius; }
}
// Loop through and access fields
for (Planet planet : Planet.values()) {
System.out.println(planet + " - Mass: " + planet.getMass());
}Did You Know?
The values() method returns an array of all enum constants in the order they're declared. Each enum also has an ordinal() method that returns its position!
Pro Tip
Use EnumSet for efficient enum collections:
// Get weekdays only
EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);Real-World Use Cases
- Menus: Display all menu options
- Status codes: List all possible statuses
- Configuration: Iterate through settings
- Validation: Check against all enum values
›Short versionOpen if you only have a minute.
- EnumType.values() returns the constants in declaration order.
- Each call allocates a new array. Cache it if a hot loop asks for the constants repeatedly.
- valueOf expects the exact constant name. "monday" is not Day.MONDAY.
- Compare enum constants with ==. Do not compare their names as strings unless you are parsing text.
Loop an enum
Visit every constant of an enum type.
Working approach
- Call values() once and loop the array.
- Put a label or a behavior on the constant if the loop body would otherwise switch on the name.
- Parse external text with a method that explains a bad name, instead of letting valueOf throw at the edge of the program.
Walk the sample
- Day declares MONDAY then TUESDAY
- values() returns that array
- The loop prints MONDAY, then TUESDAY
The trap
Day.valueOf("monday") throws IllegalArgumentException. The name is case-sensitive and must match the constant, not a display label.
for (Day day : Day.values()) {
// declaration order, a fresh array on every values() call
}
static Day parse(String text) {
for (Day day : Day.values()) {
if (day.name().equals(text)) {
return day;
}
}
throw new IllegalArgumentException("unknown day: " + text);
}What does Day.valueOf("monday") do?
It throws IllegalArgumentException. valueOf looks up the constant name MONDAY, with that spelling.
A loop over values() is the place to match a label you defined. Hard-coding the same constants in a second switch drifts the moment someone adds a constant.
Time proportional to the number of constants. values() also allocates an array of that length.
Easy to get wrong
- Passing a display label or a lowercase name to valueOf.
- Listing the constants by hand in a second place.