假设我有一个枚举

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

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

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


当前回答

另一个实用程序以相反的方式捕获。使用标识该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”)。

其他回答

Kotlin溶液

创建一个扩展,然后调用valueOf<MyEnum>(“value”)。如果类型无效,您将得到null,并必须处理它

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

或者,您可以设置默认值,调用valueOf<MyEnum>(“value”,MyEnum.FALLACK),并避免空响应。您可以扩展特定枚举以使默认值为自动

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

或者,如果你想两者兼得,那么做第二个:

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

枚举非常有用。我一直在使用Enum为不同语言的某些字段添加描述,如以下示例:

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

然后,您可以根据传递给getDescription(Stringlang)方法的语言代码动态检索描述,例如:

String statusDescription = Status.valueOf("ACT").getDescription("en");
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;
}

使用Streams的Java 8的答案和评论的组合。它创建了一个静态Map,用于使用默认值进行查找,以防止空检查。

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

如果您不想编写自己的实用程序,请使用Google的番石榴库:

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

与内置Java函数不同,它让您检查Blah中是否存在A,并且不会引发异常。