By Malachi


2009-03-02 22:56:34 8 Comments

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?

26 comments

@Ebraheem Alrabee' 2019-06-23 08:44:06

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 getDescription(String lang) method, for example:

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

@Hans Schreuder 2017-08-01 10:17:36

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

@Bishal Jaiswal 2019-04-16 13:25:25

Fastest way to get the name of enum is to create a map of enum text and value 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.toString());
        }
    }
    public static String getEnumName(String text) {
        return map.get(text.toLowerCase());
    } 
}

@Darrell Teague 2016-06-15 16:37:01

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(),instance);
        }
        ENUM_MAP = Collections.unmodifiableMap(map);
    }

    public static MyEnum get (String name) {
        return ENUM_MAP.get(name);
    }
}

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

@dermoritz 2017-01-10 09:51:41

if Joshua Bloch said it then this is the only way to go :-). Its a shame that i always have to scroll down here.

@Novaterata 2017-04-27 17:01:13

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.

@Darrell Teague 2017-04-28 20:31:57

Java 8 certainly can/will change a lot of (better) answers on this forum. Not sure about ever having the tail (Sonar) wag the dog (application code) though.

@Daniel Pryden 2018-03-08 16:13:53

If you're going to put it in an unmodifiableMap anyway, then there's no benefit to starting with a ConcurrentHashMap. Just use a HashMap. (If you have Guava's ImmutableMap then I'd recommend that instead!)

@Darrell Teague 2018-03-09 16:47:16

Google's ImmutableMap is certainly a better (true deeply immutable) implementation but for the purpose of demonstrating an only-core-Java solution ... and focusing on the String map lookup case, only core-Java classes were used. In general, have found that ConcurrentHashMap is almost always preferred over HashMap given the overall performance profile (add, remove, modify) and simplicity versus wrapping/locking HashMap when concurrent modification has to be considered.

@Radiodef 2018-08-05 17:24:28

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.

@Darrell Teague 2018-08-24 16:48:04

The comment in code explicitly states "any map impl will do". For junior devs have found using ConcurrentHashMap as a common practice is preferrable in trade off with common sources of bugs in not synchronizing Map modifications generally.

@YoYo 2018-08-29 15:28:08

@DarrellTeague - If we are in multithreaded environment, then it is mandatory to think about the consequences of our choices. Defensive use of synchronized collections without thought runs counter to the reasons why we have concurrency in the first place. I cannot see why a collection that in principle should be an Immutable Collection can benefit from being implemented as a Concurrent Collection.

@Darrell Teague 2018-08-31 01:28:34

@YoYo - again as stated, any map impl will do and there is indeed no consequence, positive nor negative for the given impl. Please read prior comment about junior devs such that, all things considered, given that ConcurrentHashMap has no read performance penalty, has applicability as a general purpose Map impl, generally over HashMap wherein developers must think very carefully about synchronization during update. Thus herein where ConcurrentHashMap may be used with no consequence and may be needed in other cases where synchronization is needed - this seems perfectly reasonable.

@YoYo 2018-08-31 02:15:25

If that is your firm belief, then I should also advise on using synchronized (map) { ENUM_MAP = Collections.unmodifiableMap(map); } to avoid indeterministic behavior in a possible iterator being used inside the method for building the unmodifiable version - as a standard so that the junior dev does not have to think to much about those same consequences. See Synchronized Wrappers.

@Darrell Teague 2018-08-31 17:06:35

Thanks @YoYo and that is a good impl snippet in context for others to understand implications of gaining access to iterators whilst maps are being constructed/updated - a subtle and difficult to debug case.

@Enerccio 2019-05-23 08:21:52

sorry but ConcurrentHashMap is completely useless there

@JoséMi 2010-06-03 10:57:50

Another solution if the text is not the same to 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;
    }
}

@whiskeysierra 2010-07-31 10:28:46

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

@Sanghyun Lee 2011-09-05 04:06:16

@whiskeysierra Jon Skeet wouldn't agree with that. stackoverflow.com/questions/1167982/…

@whiskeysierra 2011-09-29 15:04:35

@Sangdol Could you enlight us why returning null is better?

@whiskeysierra 2011-09-29 21:44:01

That comment is about the proposed answer of actually catching an exception to determine whether the string represents a valid enum value. You probably need a second method (e.g. isValid) for such a use case.

@raudi 2012-02-02 07:43:58

@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 ;-)

@JoséMi 2012-02-03 08:20:37

Well, you could also make use of @Nullable annotation to make it "readable" ;-)

@YoYo 2012-09-30 18:22:42

Ok, to convert a string into an enum constant, It is probably good to throw an exception in case of null or no match, same like valueOf does. However, think about how you would implement a method to test if a string is used by the enum constants ... example to get around all that at stackoverflow.com/a/12659023/744133

@Christophe Roussy 2012-11-08 10:29:12

Concerning error handling it always depends on where the information comes from. If your values come from an external source (user input...) over which you have no control, catch the error and show some meaningful message if possible. In case the value passed to valueOf comes from your own internal code you should catch the errors and fail hard (log and crash) you probably have a bug and it can be fixed.

@Jan Tacci 2013-03-24 04:33:01

I have a really dumb question... in your fromString method right after where you do the equalsIgnoreCase you have b.text. Text is a private member of the enum class how can you access it?

@JoséMi 2013-03-27 06:16:18

@Jan: Because the code itself is inside the enum class and, of course, it has visibility over all attributes and methods of that class.

@Tyzoid 2013-05-24 14:05:14

@raudi I prefer null in this case, because when I go to get the value, I find it more pragmatic to check if(returnval == null) than catch the exception. It works better idealistically too: does it make more sense to return an empty result if it doesn't match? or throw an error? I think it makes more sense to return an empty result.

@raudi 2013-05-27 17:05:33

@Tyzoid: I didn't say it's wrong I didn't even say it's bad practice, I just said that throwing an exception looks more appropriate. Think about what the caller has to do: if null is returned, then the return value has to be checked after each and every call unless you want to catch NPE, which you shouldn't ;-). Now look at what happens if an exception is thrown: The caller can decide on what level he wants to catch it: globally catch Exception, global catch the specific Exception or catch the specific Exception on single calls or any combination thereof. Surely a lot nicer to use...

@trutheality 2013-05-29 21:45:55

@Tyzoid @raudi To be fair, especially if you are writing code to last and for others to use, the appropriate thing to do is something like what the Queue interface does with remove vs. poll -- have two versions of the method, one that returns null on (a very predictable and common) failure, and one that throws an exception, then let whoever is using it decide what to use based on what the larger application warrants.

@Snicksie 2013-08-01 07:16:47

I guess if (text == null) return null; is better than if (text != null) { ....} return null. The first way is easier to understand.

@Kevin Meredith 2013-12-05 21:21:57

@Gus 2014-06-28 01:12:18

text.equalsIgnoreCase(b.text) may throw null pointer exception if null is passed to fromString() whereas b.text.equalsIgnoreCase(text) will not (given the listed enum instances).

@JoséMi 2014-07-02 05:50:03

@Gus, please, read two lines before the one you says there is an error: if (text != null) {...

@Gus 2014-07-05 13:26:02

Sorry, wrote to fast... It's not an error. The null check can be avoided. This is just like "foo".equals(bar) instead of bar.equals("foo")

@FearlessHyena 2014-10-03 20:03:24

@JoséMi Might also be a good idea to override the default toString() and make it return 'text'

@Paul 2016-05-11 16:46:21

The addition of the text field and getText() methods is not necessary as the code could just as easily have used the automatically generated name() method. It is also possible to write a public static <E extends Enum<E>> com.mylibs.Enums.fromString(E enumType, String s) that would work for any Enum type.

@chrisdowney 2017-07-12 21:57:16

An alternative in many cases is to have an explicit UNKNOWN value for the enum - that way you can avoid NPEs and still be able to check for unknown values.

@Dawood ibn Kareem 2017-09-14 20:03:53

To be fair to Jon Skeet, the question he was answering was how to do this without throwing and catching an exception. The fact that he answered the question as asked doesn't mean he believes it's a good idea. @SanghyunLee

@Martin Marconcini 2018-04-10 20:03:55

For what is worth, Kotlin… The valueOf() method throws an IllegalArgumentException if the specified name does not match any of the enum constants defined in the class.

@Manu 2017-07-13 13:38:02

My 2 cents here: using Java8 Streams + 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));
    }
}

** EDIT **

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

@Adam 2018-05-10 11:35:00

Alternatively to allow you to write more readable switch blocks, you can .orElse(null) instead of .orElseThrow() so that you can code the exception throw in the default clause - and include more useful info when required. And to make it more lenient you could use v -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())

@Carlos Heuberger 2018-08-02 20:58:50

or just return the Optional from findFirst(), allowing the user to decide if he wants .orElse(null), orElseThrow() or whatever....

@Radiodef 2018-12-23 23:34:13

Declaring a public static MyEnum valueOf(String) is actually a compilation error, since it's the same as the one implicitly defined, so the older version of your answer is actually better. (jls, ideone)

@Hans Schreuder 2019-05-23 10:57:55

In my option it is better to avoid Exceptions and use Optional. Next to that we should void null and use Optional instead as well.

@LuCio 2018-08-02 19:57:17

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.

@DCO 2017-12-30 07:38:31

What about?

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

@Michael Myers 2009-03-02 22:57:44

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.

@Brett 2013-12-17 17:37:05

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.

@Kevin Meredith 2014-02-12 21:24:44

@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?

@Michael Myers 2014-02-14 04:10:45

@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.

@treesAreEverywhere 2014-03-07 00:43:08

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

@Ti Strga 2014-05-30 19:31:19

@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.)

@Bill K 2015-11-19 17:39:26

Great answer--in addition I've found adding a few little helper methods to enums helps a lot... For instance, if you create a static map of lower-case entries in the constructor then you can add a method that looks the enum up in a case-insensitive way, or converts underbars to spaces so user input like "Second Entry" could map to an enum SECOND_ENTRY.

@nemetroid 2017-06-29 08:54:03

Why does @Brett's comment have so many votes? Of course it's case sensitive and doesn't tolerate extraneous whitespace, anything else would be insane.

@maaartinus 2018-08-21 22:48:16

@nemetroid Not that insane, given that whitespace is not allowed in names and that all enum names are uppecase by convention. So a tolerant lookup method is possible as the result stays unique. However, users may require something even more tolerant and therefore it's best to provide a canonical strict version (and there are other problems like uppercasing being locale-sensitive and whatever).

@Bex 2018-08-22 14:27:21

Upvote, but this post would be even better with a mention of Enum::name

@lance.dolan 2017-01-26 20:30:18

Adding on to the top rated 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
}

@Novaterata 2017-04-27 17:10:02

In Java 8 the static Map pattern is even easier and is my preffered 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);
    }
}

@John Hemming 2016-08-30 09:11:58

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

@Lambart 2016-11-15 01:49:05

Looks good, but essentially the same as Patrick Arnesen's answer...

@Moesio 2016-02-24 11:23:07

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").

@Murtaza Kanchwala 2015-07-02 11:54:04

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 String method 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 e.g. if you provide "PERSON" in the fromEnumName it'll return you the Value of Enum i.e. "Person"

@pjklauser 2015-10-22 06:46:11

Apache's commons-lang library has a static function org.apache.commons.lang3.EnumUtils.getEnum which will map a String to your Enum type. Same answer essentially as Geoffreys but why roll your own when it's out there in the wild already.

@Sisyphus 2015-09-23 09:08:33

O(1) method inspired from thrift generated code which utilize 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;
        }

}

@tom 2014-10-10 10:10:17

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/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 info on avoiding null with Optional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional

@KNU 2014-10-29 12:22:18

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

  • You can use name() method to get name of any Enum constants. String literal used to write enum constants is their name.
  • Similarly 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 valueOf() method to convert any String to 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, valueOf() method returns an Enum constant Gender.MALE, calling name on that returns "MALE".

@Prasobh.Kollattu 2011-11-09 09:50:35

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

@bakoyaro 2011-11-09 18:15:06

take a look at this link for guides on answering and asking questions on stackoverflow.com: stackoverflow.com/faq

@Rup 2011-11-14 12:40:14

That's more or less the same as JoséMi's answer

@Patrick Arnesen 2011-12-01 21:53:29

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

@Stijn de Witt 2015-07-26 13:35:57

This variation is doing it correctly: equalsIgnoreCase is the way to go. +1

@Darrell Teague 2018-08-13 17:26:57

Like case insensivity but ... prefer Enums over (random) String assignments for keys and ... minor but iterating is less performant for such a possibly repetative lookup. Hence impl of EnumMap et al.

@MasterJoe2 2018-11-26 20:49:08

This does not work ! I changed the equalsIgnoreCase to equals for my purpose. The code failed even though both inputs to equals were exactly the same.

@Geoffrey Zheng 2009-11-12 15:52:49

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.

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

@whiskeysierra 2010-07-31 10:14:55

That empty catch block really drives me nuts, sorry.

@Martin Schröder 2011-11-15 17:09:06

@LazloBonin: Exceptions are for exceptional conditions, not for control flow. Get yourself a copy of Effective Java.

@Nate C-K 2011-11-30 19:26:55

If the Java API you want to use throws an exception and you don't want your code to throw one, you can either swallow the exception like this, or re-write the logic from scratch so no exception is thrown in the first place. Swallowing the exception is often the lesser evil.

@raudi 2012-02-02 07:52:31

Horrible! Always, always catch exceptions where you can handle them. The example above is a perfect example how to NOT do it. Why? So it returns NULL, and the caller then has to check against NULL or throw a NPE. If the caller knows how to handle the situation then doing an if vs. try-catch may look a bit more elegant, BUT if he can't handle he has to pass null again and the caller of the caller again has to check against NULL, etc. etc.

@Adrian M 2012-02-06 08:19:39

To be fair to the solution above, there are really uses cases requiring you to return null instead of throwing IllegalArgumentException and break the flow of your program, for instance, mapping enums between a web service schema and a database schema wherein they are not always one-to-one. However, I agree that the catch block should never be left empty. Put some code like log.warn or something for tracking purpose.

@Manimaran Selvan 2012-05-17 18:49:52

Absolutely! Logging the exception is a sure thing. But I agree with swallowing exceptions.

@Geoffrey Zheng 2012-08-20 20:28:02

Now I would just use Guava's Enums. Note the different treatment of invalid input: getIfPresent returns Optional.absent(), which is what I'd prefer to use; whereas valueOfFunction().apply() returns null.

@YoYo 2012-09-30 05:18:49

The problems starts when you would want to write a static method that tests if a string matches an enum instance. The only way to test against the different enum values is to actually call the valueOf function. If it throws, result is false.

@urig 2013-02-12 08:37:30

Am I missing Something? What is the added value of the above methods compared to simply using: MyEnum.valueOf(name) ?

@Brad Mace 2014-05-15 19:49:57

@urig they're case insensitive, unlike valueOf

@Stijn de Witt 2015-07-26 13:29:59

If you're going to write a separate routine for case-insensitive comparison, then why not really do a case-insensitive check using String.equalsIgnoreCase instead of this hardcoded toUpperCase?

@pjklauser 2015-10-22 06:47:10

Equivalent to apache-common's EnumUtils getEnum method

@nemetroid 2017-06-29 08:51:45

@pjklauser No, EnumUtils' getEnum method does not do case insensitive lookup.

@Rob Stoecklein 2018-01-09 18:59:27

I like this utility. We've added a "default" parameter in case the enumeration cannot be determined: final @Nullable T def

@Darrell Teague 2019-01-14 15:44:40

A side-discussion now but... a better practice is to return an Optional if that is what is what was intended (e.g., could reasonably be "unknown/undefined"). Then NPE is gone and yet the lookup failure doesn't return an Exception as a means of control flow.

@javabrew 2014-08-22 20:07:47

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

@Andrejs 2014-04-02 20:12:18

If you don't want to write your own utility use Google's 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.

@javaProgrammer 2016-08-19 00:02:58

sad part is, this returns a google Optional and not java Optional

@Darrell Teague 2018-08-13 17:30:08

True. Exoected though. Google and Netflix have great Java libs. Where there is overlap with Java catch-up classes implemented in newer versions inevitably causes trouble. Kind of have to be all in on one vendor lib.

@João Portela 2009-05-09 16:33:36

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.

edit
Changed toUpperCase to toUpperCase(Locale.ENGLISH) based on tc. comment and the java docs

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

@tc. 2012-11-28 15:43:24

Be wary of the default locale!

@sulai 2013-09-02 17:44:51

For you Android users out there, I would like to point out that Android documentation explicitly encourages the usage of Locale.US for machine readable input/output.

@Holloway 2014-08-14 10:57:16

Is upper case different in different places?

@João Portela 2014-08-25 11:26:22

@Trengot Yes.

@Stijn de Witt 2015-07-26 13:34:22

@Trengot Yes, unfortunately. Turkey is a good example. Combine this with Java's broken handling of default charsets (defaults to Latin on Windows instead of Unicode) and you'll find it's nearly always unsafe to use the default versions of methods that accept a charset or locale. You should almost always explicitly define them.

@Darrell Teague 2018-05-29 20:45:59

Not sure Java's "default" charsets et al are "broken" per se but granted, defaulting to UTF-8 in lieu of overrides (which should be done always to be explicit) would have made better systems for junior programmers who commonly fail to understand charset concepts.

@Peter Lawrey 2009-05-09 17:23:23

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

@Murtaza Kanchwala 2015-06-28 18:58:12

Case sensitive, not helping!

@Peter Lawrey 2015-06-29 10:18:25

@MurtazaKanchwala Can you clarify your comment? What are you trying to do?

@Murtaza Kanchwala 2015-06-29 17:45:51

Hi @PeterLawrey, I was tring to fetch an Enum from a String public enum ObjectType { PERSON("Person") public String parameterName; ObjectType(String parameterName) { this.parameterName = parameterName; } public String getParameterName() { return this.parameterName; } public static ObjectType fromString(String parameterName) { if (parameterName != null) { for (ObjectType objType : ObjectType.values()) { if (parameterName.equalsIgnoreCase(objType.parameterName)) { return objType; } } } return null; } }

@Vikram 2011-11-29 05:02:25

Another way of doing this by using implicit static method name() of Enum. name will return the exact string used to create that enum which can be used to check against 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

@YoYo 2012-09-30 18:01:39

This is essentially what valueOf does for you. This static method does not offer anything extra, exception et all. Then the if/else constructs are highly dangerous ... any new enum constant added will cause this method to break without change.

@YoYo 2012-09-30 18:18:33

Consider also this example of how we can use valueOf for doing a case insensitive lookup, or how we can avoid it's exception and employ aliases to provide alternative names: stackoverflow.com/a/12659023/744133

@nrubin29 2014-04-21 00:39:07

name() is not static.

Related Questions

Sponsored Content

26 Answered Questions

[SOLVED] How do I enumerate an enum in C#?

81 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

58 Answered Questions

[SOLVED] How do I read / convert an InputStream into a String in Java?

36 Answered Questions

[SOLVED] String representation of an Enum

  • 2009-01-08 14:15:55
  • user29964
  • 736247 View
  • 879 Score
  • 36 Answer
  • Tags:   c# enums

22 Answered Questions

[SOLVED] Convert a string to an enum in C#

  • 2008-08-19 12:51:55
  • Ben Mills
  • 565056 View
  • 727 Score
  • 22 Answer
  • Tags:   c# string enums

14 Answered Questions

[SOLVED] Comparing Java enum members: == or equals()?

  • 2009-11-17 17:26:27
  • Matt Ball
  • 593516 View
  • 1576 Score
  • 14 Answer
  • Tags:   java enums

43 Answered Questions

[SOLVED] How do I convert a String to an int in Java?

45 Answered Questions

[SOLVED] How to generate a random alpha-numeric string?

54 Answered Questions

[SOLVED] Creating a memory leak with Java

26 Answered Questions

[SOLVED] Get int value from enum in C#

  • 2009-06-03 06:46:39
  • jim
  • 1327477 View
  • 1612 Score
  • 26 Answer
  • Tags:   c# enums casting int

Sponsored Content