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

前端 未结 27 2226
旧巷少年郎
旧巷少年郎 2020-11-21 10:53

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

相关标签:
27条回答
  • 2020-11-21 11:34

    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();
        }
    }
    
    0 讨论(0)
  • 2020-11-21 11:36

    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
    }
    
    0 讨论(0)
  • 2020-11-21 11:40

    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;
            }
    
    }
    
    0 讨论(0)
  • 2020-11-21 11:42

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

    0 讨论(0)
  • 2020-11-21 11:43

    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
    0 讨论(0)
  • 2020-11-21 11:43

    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"

    0 讨论(0)
提交回复
热议问题