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

JavaEnums

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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;
    }
}

Solution 3 - Java

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

Solution 4 - Java

Here's a nifty utility I use:

/**
 * A common method for all enums since they can't have another base class
 * @param <T> Enum type
 * @param c enum type. All enums must be all caps.
 * @param string case insensitive
 * @return corresponding enum, or null
 */
public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) {
    if( c != null && string != null ) {
        try {
            return Enum.valueOf(c, string.trim().toUpperCase());
        } catch(IllegalArgumentException ex) {
        }
    }
    return null;
}

Then in my enum class I usually have this to save some typing:

public static MyEnum fromString(String name) {
    return getEnumFromString(MyEnum.class, name);
}

If your enums are not all caps, just change the Enum.valueOf line.

It is too bad I can't use T.class for Enum.valueOf as T is erased.

Solution 5 - Java

You should also be careful with your case. Let me explain: doing Blah.valueOf("A") works, but Blah.valueOf("a") will not work. Then again Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) would work.

On Android you should use Locale.US, as sulai points out.

Solution 6 - Java

In Java 8 or later, using Streams:

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 Optional<Blah> fromText(String text) {
        return Arrays.stream(values())
          .filter(bl -> bl.text.equalsIgnoreCase(text))
          .findFirst();
    }
}

Solution 7 - Java

Here's a method that can do it for any Enum, and is case insensitive.

/** 
 * Finds the value of the given enumeration by name, case-insensitive. 
 * Throws an IllegalArgumentException if no match is found.  
 **/
public static <T extends Enum<T>> T valueOfIgnoreCase(
        Class<T> enumeration, String name) {

    for (T enumValue : enumeration.getEnumConstants()) {
        if (enumValue.name().equalsIgnoreCase(name)) {
            return enumValue;
        }
    }

    throw new IllegalArgumentException(String.format(
        "There is no value with name '%s' in Enum %s",
        name, enumeration.getName()
    ));
}

Solution 8 - Java

Using Blah.valueOf(string) is best, but you can use Enum.valueOf(Blah.class, string) as well.

Solution 9 - Java

My two cents here: using Java 8 Streams and checking an exact string:

public enum MyEnum {
    VALUE_1("Super"),
    VALUE_2("Rainbow"),
    VALUE_3("Dash"),
    VALUE_3("Rocks");

    private final String value;

    MyEnum(String value) {
        this.value = value;
    }

    /**
     * @return the Enum representation for the given string.
     * @throws IllegalArgumentException if unknown string.
     */
    public static MyEnum fromString(String s) throws IllegalArgumentException {
        return Arrays.stream(MyEnum.values())
                .filter(v -> v.value.equals(s))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("unknown value: " + s));
    }
}

I renamed the function to fromString() since naming it using that convention, you'll obtain some benefits from Java language itself; for example:

  1. Direct conversion of types at HeaderParam annotation

Solution 10 - Java

If you don't want to write your own utility, use Google's [tag:guava] library:

Enums.getIfPresent(Blah.class, "A")

Unlike the built-in Java function, it let's you check if A is present in Blah and doesn't throw an exception.

Solution 11 - Java

You may need to this:

public enum ObjectType {
    PERSON("Person");

    public String parameterName;

    ObjectType(String parameterName) {
        this.parameterName = parameterName;
    }

    public String getParameterName() {
        return this.parameterName;
    }

    // From the String method, it will return you the Enum for the provided input string
    public static ObjectType fromString(String parameterName) {
        if (parameterName != null) {
            for (ObjectType objType : ObjectType.values()) {
                if (parameterName.equalsIgnoreCase(objType.parameterName)) {
                    return objType;
                }
            }
        }
        return null;
    }
}
One more addition
   public static String fromEnumName(String parameterName) {
        if (parameterName != null) {
            for (DQJ objType : DQJ.values()) {
                if (parameterName.equalsIgnoreCase(objType.name())) {
                    return objType.parameterName;
                }
            }
        }
        return null;
    }

This will return you the Value by a Stringified Enum Name. For example, if you provide "PERSON" in the fromEnumName it'll return you the Value of Enum, i.e., "Person".

Solution 12 - Java

Another way of doing this is by using the implicit static method name() of Enum. name will return the exact string used to create that enum which can be used to check against the provided string:

public enum Blah {

    A, B, C, D;

    public static Blah getEnum(String s){
        if(A.name().equals(s)){
            return A;
        }else if(B.name().equals(s)){
            return B;
        }else if(C.name().equals(s)){
            return C;
        }else if (D.name().equals(s)){
            return D;
        }
        throw new IllegalArgumentException("No Enum specified for this string");
    }
}

Testing:

System.out.println(Blah.getEnum("B").name());


// It will print B  B

Inspiration: 10 Examples of Enum in Java

Solution 13 - Java

In Java 8 the static Map pattern is even easier and is my preferred method. If you want to use the Enum with Jackson you can override toString and use that instead of name, then annotate with @JsonValue

public enum MyEnum {
    BAR,
    BAZ;
    private static final Map<String, MyEnum> MAP = Stream.of(MyEnum.values()).collect(Collectors.toMap(Enum::name, Function.identity()));
    public static MyEnum fromName(String name){
        return MAP.get(name);
    }
}

public enum MyEnumForJson {
    BAR("bar"),
    BAZ("baz");
    private static final Map<String, MyEnumForJson> MAP = Stream.of(MyEnumForJson.values()).collect(Collectors.toMap(Object::toString, Function.identity()));
    private final String value;

    MyEnumForJson(String value) {
        this.value = value;
    }

    @JsonValue
    @Override
    public String toString() {
        return value;
    }

    public static MyEnumForJson fromValue(String value){
        return MAP.get(value);
    }
}

Solution 14 - Java

Here is a solution using Guava libraries. Method getPlanet() is case insensitive, so getPlanet ("MerCUrY") will return Planet.MERCURY.

package com.universe.solarsystem.planets;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Enums;
import com.google.common.base.Optional;

//Pluto and Eris are dwarf planets, who cares!
public enum Planet {
   MERCURY,
   VENUS,
   EARTH,
   MARS,
   JUPITER,
   SATURN,
   URANUS,
   NEPTUNE;

   public static Planet getPlanet(String name) {
      String val = StringUtils.trimToEmpty(name).toUpperCase();
      Optional <Planet> possible = Enums.getIfPresent(Planet.class, val);
      if (!possible.isPresent()) {
         throw new IllegalArgumentException(val + "? There is no such planet!");
      }
      return possible.get();
   }
}

Solution 15 - Java

Enum is very useful. I have been using Enum a lot to add a description for some fields in different languages, as the following example:

public enum Status {

    ACT(new String[] { "Accepted", "مقبول" }),
    REJ(new String[] { "Rejected", "مرفوض" }),
    PND(new String[] { "Pending", "في الانتظار" }),
    ERR(new String[] { "Error", "خطأ" }),
    SNT(new String[] { "Sent", "أرسلت" });

    private String[] status;

    public String getDescription(String lang) {
        return lang.equals("en") ? status[0] : status[1];
    }

    Status(String[] status) {
        this.status = status;
    }
}

And then you can retrieve the description dynamically based in the language code passed to the getDescription(String lang) method, for example:

String statusDescription = Status.valueOf("ACT").getDescription("en");

Solution 16 - Java

To add to the previous answers, and address some of the discussions around nulls and NPE I'm using Guava Optionals to handle absent/invalid cases. This works great for URI and parameter parsing.

public enum E {
    A,B,C;
    public static Optional<E> fromString(String s) {
        try {
            return Optional.of(E.valueOf(s.toUpperCase()));
        } catch (IllegalArgumentException|NullPointerException e) {
            return Optional.absent();
        }
    }
}

For those not aware, here's some more information on avoiding null with Optional.

Solution 17 - Java

public static MyEnum getFromValue(String value) {
    MyEnum resp = null;
    MyEnum nodes[] = values();
    for(int i = 0; i < nodes.length; i++) {
        if(nodes[i].value.equals(value)) {
            resp = nodes[i];
            break;
        }
    }
    return resp;
}

Solution 18 - Java

java.lang.Enum defines several useful methods, which is available to all enumeration types in Java:

  • You can use the name() method to get the name of any Enum constants. The string literal used to write enum constants is their name.
  • Similarly, the values() method can be used to get an array of all Enum constants from an Enum type.
  • And for the asked question, you can use the valueOf() method to convert any String to an Enum constant in Java, as shown below.

public class EnumDemo06 {
    public static void main(String args[]) {
        Gender fromString = Gender.valueOf("MALE");
        System.out.println("Gender.MALE.name() : " + fromString.name());
    }

    private enum Gender {
        MALE, FEMALE;
    }
}

Output:
Gender.MALE.name() : MALE

In this code snippet, the valueOf() method returns an Enum constant, Gender.MALE, and calling name on that returns "MALE".

Solution 19 - Java

An O(1) method inspired from Thrift-generated code which uses a hashmap.

public enum USER {
        STUDENT("jon",0),TEACHER("tom",1);

        private static final Map<String, Integer> map = new HashMap<>();

        static {
                for (USER user : EnumSet.allOf(USER.class)) {
                        map.put(user.getTypeName(), user.getIndex());
                }
        }

        public static int findIndexByTypeName(String typeName) {
                return map.get(typeName);
        }

        private USER(String typeName,int index){
                this.typeName = typeName;
                this.index = index;
        }
        private String typeName;
        private int index;
        public String getTypeName() {
                return typeName;
        }
        public void setTypeName(String typeName) {
                this.typeName = typeName;
        }
        public int getIndex() {
                return index;
        }
        public void setIndex(int index) {
                this.index = index;
        }

}

Solution 20 - Java

Use:

public enum MyEnum {
    FIRST,
    SECOND,
    THIRD;

    public static Optional<MyEnum> fromString(String value) {
        try {
            return Optional.of(MyEnum.valueOf(value));
        }catch(Exception e) {
            return Optional.empty();
        }
    }
}

Solution 21 - Java

Apache's commons-lang library has a static function [org.apache.commons.lang3.EnumUtils.getEnum][2] which will map a String to your Enum type. Same answer essentially as [Geoffrey Zheng's][3], but there isn't any need to roll your own when it's out there in the wild already.

[2]: https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/EnumUtils.html#getEnum(java.lang.Class,%20java.lang.String) "EnumUtils.getEnum" [3]: https://stackoverflow.com/questions/604424/how-to-get-an-enum-value-from-a-string-value-in-java/1723239#1723239

Solution 22 - Java

Adding on to Michael Myers' answer, with a helpful utility...

valueOf() throws two different Exceptions in cases where it doesn't like its input.

  • IllegalArgumentException
  • NullPointerExeption

If your requirements are such that you don't have any guarantee that your String will definitely match an enum value, for example if the String data comes from a database and could contain old version of the enum, then you'll need to handle these often...

So here's a reusable method I wrote which allows us to define a default Enum to be returned if the String we pass doesn't match.

private static <T extends Enum<T>> T valueOf( String name , T defaultVal) {
        try {
            return Enum.valueOf(defaultVal.getDeclaringClass() , name);
        } catch (IllegalArgumentException | NullPointerException e) {
            return defaultVal;
        }
    }

Use it like this:

public enum MYTHINGS {
    THINGONE,
    THINGTWO
}

public static void main(String [] asd) {
  valueOf("THINGTWO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGTWO
  valueOf("THINGZERO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGONE
}

Solution 23 - Java

As a switch-version has not been mentioned yet I introduce it (reusing OP's enum):

  private enum Blah {
    A, B, C, D;

    public static Blah byName(String name) {
      switch (name) {
        case "A":
          return A;
        case "B":
          return B;
        case "C":
          return C;
        case "D":
          return D;
        default:
          throw new IllegalArgumentException(
            "No enum constant " + Blah.class.getCanonicalName() + "." + name);
      }
    }
  }

Since this don't give any additional value to the valueOf(String name) method, it only makes sense to define an additional method if we want have a different behavior. If we don't want to raise an IllegalArgumentException we can change the implementation to:

  private enum Blah {
    A, B, C, D;

    public static Blah valueOfOrDefault(String name, Blah defaultValue) {
      switch (name) {
        case "A":
          return A;
        case "B":
          return B;
        case "C":
          return C;
        case "D":
          return D;
        default:
          if (defaultValue == null) {
            throw new NullPointerException();
          }
          return defaultValue;
      }
    }
  }

By providing a default value we keep the contract of Enum.valueOf(String name) without throwing an IllegalArgumentException in that manner that in no case null is returned. Therefore we throw a NullPointerException if the name is null and in case of default if defaultValue is null. That's how valueOfOrDefault works.

This approach adopts the design of the Map-Interface which provides a method Map.getOrDefault(Object key, V defaultValue) as of Java 8.

Solution 24 - Java

I was looking for an answer to find the "blah" name and not its value (not the text). Based on Manu's answer, I find this code useful:

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 valueOfCode(String blahCode) throws IllegalArgumentException {
    Blah blah = Arrays.stream(Blah.values())
            .filter(val -> val.name().equals(blahCode))
            .findFirst()
            .orElseThrow(() -> new IllegalArgumentException("Unable to resolve blah: " + blahCode));

    return blah;
}

}

Solution 25 - Java

Enum valueOf()

An enum class automatically gets a static valueOf() method in the class when compiled. The valueOf() method can be used to obtain an instance of the enum class for a given String value.

For example:

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println(Strings.TWO.name());
    }
    enum Strings {
        ONE, TWO, THREE
    }
}

Solution 26 - Java

Another utility capturing in reverse way. Using a value which identify that Enum, not from its name.

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.EnumSet;

public class EnumUtil {

	/**
	 * Returns the <code>Enum</code> of type <code>enumType</code> whose a 
	 * public method return value of this Enum is 
	 * equal to <code>valor</code>.<br/>
	 * Such method should be unique public, not final and static method 
	 * declared in Enum.
	 * In case of more than one method in match those conditions
	 * its first one will be chosen.
	 * 
	 * @param enumType
	 * @param value
	 * @return 
	 */
	public static <E extends Enum<E>> E from(Class<E> enumType, Object value) {
		String methodName = getMethodIdentifier(enumType);
		return from(enumType, value, methodName);
	}

	/**
	 * Returns the <code>Enum</code> of type <code>enumType</code> whose  
	 * public method <code>methodName</code> return is 
	 * equal to <code>value</code>.<br/>
	 *
	 * @param enumType
	 * @param value
	 * @param methodName
	 * @return
	 */
	public static <E extends Enum<E>> E from(Class<E> enumType, Object value, String methodName) {
		EnumSet<E> enumSet = EnumSet.allOf(enumType);
		for (E en : enumSet) {
			try {
				String invoke = enumType.getMethod(methodName).invoke(en).toString();
				if (invoke.equals(value.toString())) {
					return en;
				}
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}
	
	private static String getMethodIdentifier(Class<?> enumType) {
		Method[] methods = enumType.getDeclaredMethods();
		String name = null;
		for (Method method : methods) {
			int mod = method.getModifiers();
			if (Modifier.isPublic(mod) && !Modifier.isStatic(mod) && !Modifier.isFinal(mod)) {
				name = method.getName();
				break;
			}
		}
		return name;
	}
}

Example:

public enum Foo {
	ONE("eins"), TWO("zwei"), THREE("drei");

	private String value;

	private Foo(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}
}

EnumUtil.from(Foo.class, "drei") returns Foo.THREE, because it will use getValue to match "drei", which is unique public, not final and not static method in Foo. In case Foo has more than on public, not final and not static method, for example, getTranslate which returns "drei", the other method can be used: EnumUtil.from(Foo.class, "drei", "getTranslate").

Solution 27 - Java

public enum ToggleStatusUpdate {
    OFF("off", 1),
    ON("on", 2);
    
    private final String name;
    private final int position;
    
    private ToggleStatusUpdate(String name, int position) {
        this.name = name;
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public int getPosition() {
        return position;
    }
    
	public static int getPositionForName(String name) {
        for(ToggleStatusUpdate toggleStatusUpdate : ToggleStatusUpdate.values()) {
            if (toggleStatusUpdate.getName().equals(name)) {
                return toggleStatusUpdate.getPosition();
            }
        }
        return -1;
    }

	public static void main(String[] args) {
		System.out.println(ToggleStatusUpdate.getPositionForName("off"));
	}
}

Solution 28 - Java

A combination of answers and comments for Java 8 using Streams. It creates a static Map for lookup with the opportunity of a default value, to prevent null checks.

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

    private static final Map<String, Blah> ENUM_MAP = Stream.of(Blah.values())
            .collect(Collectors.toMap(Enum::name, Function.identity()));

    public static Blah of(final String name) {
        return ENUM_MAP.getOrDefault(name, INVALID);
    }
}

// e.g.
Blah.of("A");
A

Blah.of("X")
INVALID

Solution 29 - Java

I like to use this sort of process to parse commands as strings into enumerations. I normally have one of the enumerations as "unknown" so it helps to have that returned when the others are not found (even on a case insensitive basis) rather than null (that meaning there is no value). Hence I use this approach.

static <E extends Enum<E>> Enum getEnumValue(String what, Class<E> enumClass) {
	Enum<E> unknown=null;
    for (Enum<E> enumVal: enumClass.getEnumConstants()) {  
		if (what.compareToIgnoreCase(enumVal.name()) == 0) {
			return enumVal;
		}
		if (enumVal.name().compareToIgnoreCase("unknown") == 0) {
			unknown=enumVal;
		}
    }  
	return unknown;
}

Solution 30 - Java

The fastest way to get the name of enum is to create a map of enum text and values when the application start, and to get the name call the function Blah.getEnumName():

public enum Blah {
    A("text1"),
    B("text2"),
    C("text3"),
    D("text4");

    private String text;
    private HashMap<String, String> map;
    Blah(String text) {
    this.text = text;
    }

    public String getText() {
      return this.text;
    }

    static{
      createMapOfTextAndName();
    }

    public static void createMapOfTextAndName() {
        map = new HashMap<String, String>();
        for (Blah b : Blah.values()) {
             map.put(b.getText(),b.name());
        }
    }
    public static String getEnumName(String text) {
        return map.get(text.toLowerCase());
    }
}

Solution 31 - Java

Kotlin Solution

Create an extension and then call valueOf<MyEnum>("value"). If the type is invalid, you'll get null and have to handle it

inline fun <reified T : Enum<T>> valueOf(type: String): T? {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        null
    }
}

Alternatively, you can set a default value, calling valueOf<MyEnum>("value", MyEnum.FALLBACK), and avoiding a null response. You can extend your specific enum to have the default be automatic

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        default
    }
}

Or if you want both, make the second:

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMalachiView Question on Stackoverflow
Solution 1 - JavaMichael MyersView Answer on Stackoverflow
Solution 2 - JavaJoséMiView Answer on Stackoverflow
Solution 3 - JavaDarrell TeagueView Answer on Stackoverflow
Solution 4 - JavaGeoffrey ZhengView Answer on Stackoverflow
Solution 5 - JavaJoão PortelaView Answer on Stackoverflow
Solution 6 - JavaHans SchreuderView Answer on Stackoverflow
Solution 7 - JavaPatrick ArnesenView Answer on Stackoverflow
Solution 8 - JavaPeter LawreyView Answer on Stackoverflow
Solution 9 - JavaManu ArteroView Answer on Stackoverflow
Solution 10 - JavaAndrejsView Answer on Stackoverflow
Solution 11 - JavaMurtaza KanchwalaView Answer on Stackoverflow
Solution 12 - JavaVikramView Answer on Stackoverflow
Solution 13 - JavaNovaterataView Answer on Stackoverflow
Solution 14 - JavajavabrewView Answer on Stackoverflow
Solution 15 - JavaEbraheem AlrabeeaView Answer on Stackoverflow
Solution 16 - JavatomView Answer on Stackoverflow
Solution 17 - JavaPrasobh.KollattuView Answer on Stackoverflow
Solution 18 - JavaKNUView Answer on Stackoverflow
Solution 19 - JavaSisyphusView Answer on Stackoverflow
Solution 20 - JavaDCOView Answer on Stackoverflow
Solution 21 - JavapjklauserView Answer on Stackoverflow
Solution 22 - Javalance.dolanView Answer on Stackoverflow
Solution 23 - JavaLuCioView Answer on Stackoverflow
Solution 24 - Javaorly.sharonView Answer on Stackoverflow
Solution 25 - JavaNitya Nand PandeyView Answer on Stackoverflow
Solution 26 - JavaMoesioView Answer on Stackoverflow
Solution 27 - JavaSwapnil GangradeView Answer on Stackoverflow
Solution 28 - JavaAnd-yView Answer on Stackoverflow
Solution 29 - JavaJohn HemmingView Answer on Stackoverflow
Solution 30 - JavaBishal JaiswalView Answer on Stackoverflow
Solution 31 - JavaGiboltView Answer on Stackoverflow