Java
Enum
Programming
String Manipulation
Coding Tips

Java Check if enum contains a given string?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

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.

Related reading
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
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.