Java
Enum
Programming
String Manipulation
Coding Tips

Java Check if enum contains a given string?

Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms

Introduction

To check if a Java enum contains a given string, use Arrays.stream(MyEnum.values()).anyMatch(e -> e.name().equals(input)). This avoids the IllegalArgumentException that Enum.valueOf() throws for invalid values. This article covers all the approaches, including a high-performance lookup set for hot paths, and handles the common complications like case-insensitive matching and custom enum fields.

The Enum We Will Use

All examples use this enum:

java
public enum Status {
    PENDING, ACTIVE, INACTIVE, DELETED;
}

The cleanest approach for a simple existence check:

java
1import java.util.Arrays;
2
3public static boolean contains(String value) {
4    return Arrays.stream(Status.values())
5                 .anyMatch(status -> status.name().equals(value));
6}
7
8// Usage
9contains("ACTIVE");    // true
10contains("active");    // false (case-sensitive)
11contains("UNKNOWN");   // false
12contains(null);        // throws NullPointerException

Null-safe version

java
1public static boolean contains(String value) {
2    return value != null && Arrays.stream(Status.values())
3                                  .anyMatch(status -> status.name().equals(value));
4}

Method 2: valueOf with Exception Handling

Enum.valueOf() returns the enum constant if it exists, or throws IllegalArgumentException if it does not:

java
1public static boolean contains(String value) {
2    try {
3        Status.valueOf(value);
4        return true;
5    } catch (IllegalArgumentException | NullPointerException e) {
6        return false;
7    }
8}

This works but using exceptions for control flow is considered a code smell. The exception is not free either: constructing the stack trace has a measurable cost, especially when called frequently with invalid values.

Method 3: Pre-built HashSet Lookup (Best for Performance)

If you check membership frequently (e.g., validating incoming API requests), build a Set once and reuse it:

java
1import java.util.Arrays;
2import java.util.Set;
3import java.util.stream.Collectors;
4
5public enum Status {
6    PENDING, ACTIVE, INACTIVE, DELETED;
7
8    private static final Set<String> NAMES = Arrays.stream(values())
9            .map(Enum::name)
10            .collect(Collectors.toUnmodifiableSet());
11
12    public static boolean contains(String value) {
13        return NAMES.contains(value);
14    }
15}
16
17// Usage
18Status.contains("ACTIVE");    // true - O(1) lookup
19Status.contains("UNKNOWN");   // false - O(1) lookup
20Status.contains(null);        // false (Set.contains handles null)

This gives O(1) lookups instead of O(n) iteration. For enums with many constants, the difference is significant.

Method 4: Case-Insensitive Matching

API inputs often arrive in lowercase or mixed case. Here are your options:

Option A: Convert input to uppercase

java
1public static boolean containsIgnoreCase(String value) {
2    if (value == null) return false;
3    try {
4        Status.valueOf(value.toUpperCase());
5        return true;
6    } catch (IllegalArgumentException e) {
7        return false;
8    }
9}

Option B: Stream with equalsIgnoreCase

java
1public static boolean containsIgnoreCase(String value) {
2    return value != null && Arrays.stream(Status.values())
3            .anyMatch(status -> status.name().equalsIgnoreCase(value));
4}
5
6// Usage
7containsIgnoreCase("active");   // true
8containsIgnoreCase("Active");   // true
9containsIgnoreCase("ACTIVE");   // true

Option C: Pre-built case-insensitive map (best performance)

java
1import java.util.Map;
2import java.util.function.Function;
3import java.util.stream.Collectors;
4
5public enum Status {
6    PENDING, ACTIVE, INACTIVE, DELETED;
7
8    private static final Map<String, Status> LOOKUP =
9            Arrays.stream(values())
10                  .collect(Collectors.toMap(
11                      s -> s.name().toLowerCase(),
12                      Function.identity()
13                  ));
14
15    public static Status fromString(String value) {
16        return value == null ? null : LOOKUP.get(value.toLowerCase());
17    }
18
19    public static boolean containsIgnoreCase(String value) {
20        return fromString(value) != null;
21    }
22}

Method 5: Matching on Custom Fields

Enums often have custom display names, database codes, or API values:

java
1public enum Status {
2    PENDING("pending", 0),
3    ACTIVE("active", 1),
4    INACTIVE("inactive", 2),
5    DELETED("deleted", 3);
6
7    private final String label;
8    private final int code;
9
10    Status(String label, int code) {
11        this.label = label;
12        this.code = code;
13    }
14
15    public String getLabel() { return label; }
16    public int getCode() { return code; }
17
18    private static final Map<String, Status> BY_LABEL =
19            Arrays.stream(values())
20                  .collect(Collectors.toMap(Status::getLabel, Function.identity()));
21
22    private static final Map<Integer, Status> BY_CODE =
23            Arrays.stream(values())
24                  .collect(Collectors.toMap(Status::getCode, Function.identity()));
25
26    public static Status fromLabel(String label) {
27        return BY_LABEL.get(label);
28    }
29
30    public static Status fromCode(int code) {
31        return BY_CODE.get(code);
32    }
33
34    public static boolean containsLabel(String label) {
35        return BY_LABEL.containsKey(label);
36    }
37}

Usage:

java
Status.fromLabel("active");        // Status.ACTIVE
Status.fromCode(2);                // Status.INACTIVE
Status.containsLabel("archived");  // false

Method Comparison

MethodTime ComplexityHandles nullCase-insensitiveReturns Enum Value
Stream + anyMatchO(n)Must handle manuallyWith equalsIgnoreCaseNo
valueOf + try/catchO(1) amortizedThrows NPEWith toUpperCaseYes
Pre-built SetO(1)Yes (returns false)With lowercase keysNo
Pre-built MapO(1)Yes (returns null)With lowercase keysYes

Generic Utility Method

If you need to check membership across multiple enums, write a generic utility:

java
1public final class EnumUtils {
2
3    private EnumUtils() {}
4
5    public static <E extends Enum<E>> boolean contains(Class<E> enumClass, String name) {
6        return name != null && Arrays.stream(enumClass.getEnumConstants())
7                .anyMatch(e -> e.name().equals(name));
8    }
9
10    public static <E extends Enum<E>> boolean containsIgnoreCase(Class<E> enumClass, String name) {
11        return name != null && Arrays.stream(enumClass.getEnumConstants())
12                .anyMatch(e -> e.name().equalsIgnoreCase(name));
13    }
14}
15
16// Usage
17EnumUtils.contains(Status.class, "ACTIVE");              // true
18EnumUtils.containsIgnoreCase(Status.class, "active");    // true

Using Apache Commons Lang

If your project already depends on Apache Commons Lang:

java
1import org.apache.commons.lang3.EnumUtils;
2
3EnumUtils.isValidEnum(Status.class, "ACTIVE");                // true
4EnumUtils.isValidEnum(Status.class, "active");                // false
5EnumUtils.isValidEnumIgnoreCase(Status.class, "active");      // true (since Commons Lang 3.8)

Common Pitfalls

  • Using valueOf for validation. valueOf throws IllegalArgumentException for missing values. Using exceptions for expected flow (e.g., validating user input) is inefficient and makes debugging noisy. Use stream or set-based checks instead.
  • Forgetting that name() is case-sensitive. Status.valueOf("active") throws because enum names are uppercase by convention. If your input comes from user input, API payloads, or config files, normalize the case before comparing.
  • Calling values() in a loop. values() creates a new array on every call. In a hot loop, this creates GC pressure. Cache the result or use a pre-built Set/Map.
  • Null handling. Enum.valueOf(null) throws NullPointerException, not IllegalArgumentException. Always null-check your input before passing it to enum methods.
  • Assuming enum names match database/API values. Enum constants are typically UPPER_SNAKE_CASE, but your API might use camelCase or lowercase. Always use a custom field and lookup map rather than relying on name() for external values.

Summary

  • For simple checks, use Arrays.stream(values()).anyMatch(e -> e.name().equals(input)).
  • For performance-sensitive code, build a Set<String> or Map<String, YourEnum> as a static field inside the enum.
  • For case-insensitive matching, normalize to lowercase in your lookup map keys.
  • For enums with custom fields (labels, codes), create dedicated fromXxx() factory methods with pre-built maps.
  • Apache Commons Lang provides EnumUtils.isValidEnum() and isValidEnumIgnoreCase() as a zero-effort alternative.
  • Never use valueOf() as a validation mechanism in production code. The exception cost is not worth it.

Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Data Structures & Algorithms practice on Codemia

Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.

Practice algorithms