Iterating Over Enum Values in Java Using values() and valueOf()

Illustration for Iterating Over Enum Values in Java Using values() and valueOf()
By Last updated:

A common mistake developers make is to hardcode constant values or loop through integer/string arrays when working with fixed sets of options like days of the week or user roles. This approach is fragile—typos or missing values often go unnoticed at compile time but lead to runtime bugs.

Enums solve this problem with built-in iteration support via values() and valueOf() methods. These allow developers to loop through all Enum constants or fetch specific constants by name. Think of it as having an official guest list at an event—values() lets you see everyone invited, while valueOf() ensures you can only call someone by their exact registered name.

In real-world applications, this feature is vital in scenarios like:

  • Displaying dropdown menus (all Enum values)
  • Mapping user input strings to Enum constants
  • Validating configuration values
  • State machine transitions

Iterating with values()

The values() method returns an array of all Enum constants in the order they are declared.

Example: Days of the Week

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class ValuesExample {
    public static void main(String[] args) {
        for (Day day : Day.values()) {
            System.out.println(day);
        }
    }
}

Output:

MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

This makes it easy to iterate over all possible options, ensuring no value is left behind.


Fetching Specific Constants with valueOf()

The valueOf(String name) method returns the Enum constant with the given name.

public class ValueOfExample {
    public static void main(String[] args) {
        Day today = Day.valueOf("FRIDAY");
        System.out.println("Today is: " + today);
    }
}

Output:

Today is: FRIDAY

⚠️ Pitfall: If the string doesn’t match exactly (case-sensitive), IllegalArgumentException is thrown.

Day wrong = Day.valueOf("friday"); // Throws exception!

Best practice: Use Enum.valueOf() only when inputs are controlled, or wrap it with error handling for user-provided values.


Real-World Example: Enum Iteration in Menus

import java.util.Scanner;

public class RoleMenu {
    public enum Role { ADMIN, USER, GUEST }

    public static void main(String[] args) {
        System.out.println("Select your role:");
        for (Role role : Role.values()) {
            System.out.println("- " + role);
        }

        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();

        try {
            Role selected = Role.valueOf(input.toUpperCase());
            System.out.println("You selected: " + selected);
        } catch (IllegalArgumentException e) {
            System.out.println("Invalid role entered!");
        }
    }
}

This is a practical way to map user input into strongly-typed Enums safely.


Best Practices and Pitfalls

  • Use values() for safe iteration instead of maintaining your own constant arrays.
  • Always handle IllegalArgumentException when using valueOf() with external input.
  • Avoid using ordinal() for iteration—it’s brittle and depends on declaration order.
  • For performance-sensitive cases, prefer EnumSet or EnumMap.

📌 What's New in Java for Enums?

  • Java 5 – Enums introduced (values() and valueOf() became available).
  • Java 8 – Stream API introduced, making Enum iteration more powerful. Example:
    Arrays.stream(Day.values()).forEach(System.out::println);
    
  • Java 9 – Module restrictions impacted reflective Enum handling.
  • Java 17 – Sealed classes offer an alternative for closed hierarchies, complementing Enums.
  • Java 21 – Switch pattern matching works seamlessly with Enum constants.

Summary + Key Takeaways

  • values() lets you iterate over all Enum constants safely.
  • valueOf() maps strings to Enum constants but requires careful error handling.
  • Prefer Enums over arrays of constants for clarity and safety.
  • Use EnumSet or EnumMap for high-performance Enum collections.
  • Streams and lambdas make iteration more expressive in modern Java.

FAQ: Iterating Over Enum Values

Q1. Why use values() instead of custom arrays?
Because values() is auto-generated, always up-to-date, and type-safe.

Q2. Can I change the order returned by values()?
No, it always follows the declaration order. Use sorting if needed.

Q3. How do I handle case-insensitive inputs with valueOf()?
Convert input with toUpperCase() or create a utility method.

Q4. What happens if valueOf() doesn’t find a match?
It throws IllegalArgumentException. Always handle exceptions for external input.

Q5. Can I iterate over Enums using Streams?
Yes, Arrays.stream(Enum.values()) is idiomatic in modern Java.

Q6. Is values() available in all Enums?
Yes, the compiler generates it for every Enum type.

Q7. Can I override values() in an Enum?
No, it’s compiler-generated and cannot be overridden.

Q8. Are Enums iterable by default?
Not directly, but values() returns an array that can be looped over.

Q9. Is it better to use ordinal() for iteration?
No, ordinal() is fragile and breaks if Enum order changes. Use values() instead.

Q10. How do I persist Enum values safely in JPA?
Use @Enumerated(EnumType.STRING) to avoid ordinal-based persistence issues.

Q11. Can Enums be used as keys in a Map?
Yes, but prefer EnumMap for efficiency.

Q12. Can I use valueOf() for user input mapping?
Yes, but always handle invalid input gracefully.