假设我有一个枚举

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

我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?

Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?


当前回答

获取enum名称的最快方法是在应用程序启动时创建enum文本和值的映射,并调用函数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());
    }
}

其他回答

一种O(1)方法,灵感来自Thrift生成的代码,该代码使用哈希图。

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

}

另一个实用程序以相反的方式捕获。使用标识该Enum的值,而不是从其名称。

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

例子:

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”)返回Foo.THREE,因为它将使用getValue来匹配“drei“,这是Foo中唯一的公共方法,不是final方法,也不是静态方法。如果Foo在public、非final和非静态方法上有多个,例如,getTranslate返回“drei”,则可以使用另一个方法:EnumUtil.from(Foo.class,“drei”,“getTranslate”)。

您可能需要:

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

再增加一项

   public static String fromEnumName(String parameterName) {
        if (parameterName != null) {
            for (DQJ objType : DQJ.values()) {
                if (parameterName.equalsIgnoreCase(objType.name())) {
                    return objType.parameterName;
                }
            }
        }
        return null;
    }

这将通过字符串化枚举名称返回值。例如,如果在fromEnumName中提供“PERSON”,它将返回Enum的值,即“PERSON”。

是的,Blah.valueOf(“A”)会给你Blah.A。

请注意,名称必须完全匹配,包括大小写:Blah.valueOf(“a”)和Blah.valueOf(“a”)都会引发IllegalArgumentException。

静态方法valueOf()和values()是在编译时创建的,不会出现在源代码中。不过,它们确实出现在Javadoc中;例如,Dialog.ModalityType显示了这两种方法。

你也应该小心处理你的案子。让我解释一下:Blah.valueOf(“A”)有效,但Blah.valueOf(“A”)无效。然后Blah.valueOf(“a”.toUpperCase(Locale.ENGLISH))也会起作用。

在Android上,你应该使用Locale.US,正如苏拉指出的那样。