Categories
enums java

How to get an enum value from a string value in Java

2268

Say I have an enum which is just

public enum Blah {
    A, B, C, D
}

and I would like to find the enum value of a string, for example "A" which would be Blah.A. How would it be possible to do this?

Is the Enum.valueOf() the method I need? If so, how would I use this?

0

    2528

    Yes, Blah.valueOf("A") will give you Blah.A.

    Note that the name must be an exact match, including case: Blah.valueOf("a") and Blah.valueOf("A ") both throw an IllegalArgumentException.

    The static methods valueOf() and values() are created at compile time and do not appear in source code. They do appear in Javadoc, though; for example, Dialog.ModalityType shows both methods.

    9

    • 114

      For reference, the Blah.valueOf("A") method is case sensitive and doesn’t tolerate extraneous whitespace, thus the alternate solution proposed below by @JoséMi.

      – Brett

      Dec 17, 2013 at 17:37


    • 3

      @Michael Myers, Since this answer is the most voted up by far, should I understand that it’s good practice to define an enum and its String value to be exactly the same?

      Feb 12, 2014 at 21:24


    • 4

      @KevinMeredith: If you mean the toString() value, no, I wouldn’t say that. name() will get you the actual defined name of the enum constant unless you override it.

      – Michael Myers

      Feb 14, 2014 at 4:10

    • 4

      What exactly do you mean by “are created at compile time and do not appear in source code.” ?

      Mar 7, 2014 at 0:43

    • 8

      @treesAreEverywhere More specifically, those methods are generated (or synthesized) by the compiler. The actual enum Blah {...} definition shouldn’t try to declare its own values nor valuesOf. It’s like how you can write “AnyTypeName.class” even though you never actually declared a “class” member variable; the compiler makes it all Just Work. (This answer may no longer be useful to you 3 months later, but just in case.)

      – Ti Strga

      May 30, 2014 at 19:31


    1000

    Another solution if the text is not the same as the enumeration value:

    public enum Blah {
        A("text1"),
        B("text2"),
        C("text3"),
        D("text4");
    
        private String text;
    
        Blah(String text) {
            this.text = text;
        }
    
        public String getText() {
            return this.text;
        }
    
        public static Blah fromString(String text) {
            for (Blah b : Blah.values()) {
                if (b.text.equalsIgnoreCase(text)) {
                    return b;
                }
            }
            return null;
        }
    }
    

    2

    • 452

      throw new IllegalArgumentException("No constant with text " + text + " found") would be better than return null.

      Jul 31, 2010 at 10:28

    • 64

      @Sangdol usually it’s a good thing to check what SUN – oops – Oracle is doing in the same situation. And as Enum.valueOf() is showing it IS best practice to throw a Exception in this case. Because it is an exceptional situation. “Performance optimization” is a bad excuse to write unreadable code 😉

      – raudi

      Feb 2, 2012 at 7:43


    144

    Use the pattern from Joshua Bloch, Effective Java:

    (simplified for brevity)

    enum MyEnum {
        ENUM_1("A"),
        ENUM_2("B");
    
        private String name;
    
        private static final Map<String,MyEnum> ENUM_MAP;
    
        MyEnum (String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    
        // Build an immutable map of String name to enum pairs.
        // Any Map impl can be used.
    
        static {
            Map<String,MyEnum> map = new ConcurrentHashMap<String, MyEnum>();
            for (MyEnum instance : MyEnum.values()) {
                map.put(instance.getName().toLowerCase(),instance);
            }
            ENUM_MAP = Collections.unmodifiableMap(map);
        }
    
        public static MyEnum get (String name) {
            return ENUM_MAP.get(name.toLowerCase());
        }
    }
    

    Also see:

    Oracle Java Example using Enum and Map of instances

    Execution order of of static blocks in an Enum type

    How can I lookup a Java enum from its String value

    2

    • 15

      This is even simpler in Java 8 as you can do :Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity())) I also recommend overriding toString() (passed in through constructor) and using that instead of name, especially if the Enum is associated with serializable data as this lets you control the casing without giving Sonar a fit.

      Apr 27, 2017 at 17:01


    • 13

      Static initialization is inherently synchronized, so there’s absolutely no reason to use ConcurrentHashMap here, where the map is never modified after initialization. Hence why even e.g. the example in the JLS itself uses a regular HashMap.

      – Radiodef

      Aug 5, 2018 at 17:24