假设我有一个枚举

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

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

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


当前回答

下面是我使用的一个漂亮的实用程序:

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

然后在我的enum类中,我通常使用这个来保存一些类型:

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

如果枚举不是全部大写,只需更改Enum.valueOf行。

太糟糕了,因为t被删除,我不能对Enum.valueOf使用t.class。

其他回答

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

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

如果文本与枚举值不同,则另一种解决方案:

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

另一种实现方法是使用Enum的隐式静态方法name()。name将返回用于创建枚举的确切字符串,该枚举可用于对照提供的字符串进行检查:

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

测试:

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


// It will print B  B

灵感:Java中Enum的10个示例

public enum DivisionType {
DEFAULT(0){
    @Override
    public void sort(List<SigInUserDto> SigInUserDtos) {
        SigInUserDtos.sort(new SigInUserCoinsQueueComparator());
    }
},
ASSIGNPOINTS(1) {
    @Override
    public void sort(List<SigInUserDto> SigInUserDtos) {
        SigInUserDtos.sort(new SigInUserPointsComparator());
    }
},
ASSIGNEVENORDER(2) {
    @Override
    public void sort(List<SigInUserDto> SigInUserDtos) {
        SigInUserDtos.sort(new SigInUserOrderCountComparator());
    }
};

public final Integer label;

DivisionType(Integer label) {
    this.label = label;
}

public static DivisionType getTypeById(Integer id) {
    for (DivisionType value : DivisionType.values()) {
        if (value.label == id) {
            return value;
        }
    }
    return DEFAULT;
}

public abstract void sort(List<SigInUserDto> SigInUserDtos);
}

使用枚举:DivisionType.getTypeById(object.getBalancingTypesId().intValue()).sort(sigInUserDtoList);

在这里,sort()函数在每个枚举匹配下实现(重载)。因此,基于对象“object.getBalancingTypesId().intValue()”匹配值,调用并排序特定的枚举匹配。