Cómo obtener un valor de enumeración a partir de un valor de cadena en Java

Resuelto Malachi asked hace 15 años • 32 respuestas

Digamos que tengo una enumeración que es solo

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

y me gustaría encontrar el valor de enumeración de una cadena, por ejemplo "A"cuál sería Blah.A. ¿Cómo sería posible hacer esto?

¿Es el Enum.valueOf()método que necesito? Si es así, ¿cómo usaría esto?

Malachi avatar Mar 03 '09 05:03 Malachi
Aceptado

Sí, Blah.valueOf("A")te lo daré Blah.A.

Tenga en cuenta que el nombre debe coincidir exactamente , incluido el caso: Blah.valueOf("a")y Blah.valueOf("A ")ambos arrojan un archivo IllegalArgumentException.

Los métodos estáticos valueOf()se values()crean en tiempo de compilación y no aparecen en el código fuente. Sin embargo, aparecen en Javadoc; por ejemplo, Dialog.ModalityTypemuestra ambos métodos.

Michael Myers avatar Mar 02 '2009 22:03 Michael Myers

Otra solución si el texto no es el mismo que el valor de enumeración:

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;
    }
}
JoséMi avatar Jun 03 '2010 10:06 JoséMi

Utilice el patrón de Joshua Bloch , Java efectivo :

(simplificado por brevedad)

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

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

Ver también:

Ejemplo de Oracle Java usando Enum y Mapa de instancias

Orden de ejecución de bloques estáticos en un tipo Enum

¿Cómo puedo buscar una enumeración de Java a partir de su valor de cadena?

Darrell Teague avatar Jun 15 '2016 16:06 Darrell Teague

Aquí hay una utilidad ingeniosa que uso:

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

Luego, en mi clase de enumeración, normalmente tengo esto para ahorrar algo de escritura:

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

Si sus enumeraciones no están todas en mayúsculas, simplemente cambie la Enum.valueOflínea.

Es una pena que no pueda usarlo T.classporque Enum.valueOfse Tborra.

Geoffrey Zheng avatar Nov 12 '2009 15:11 Geoffrey Zheng

También debes tener cuidado con tu caso. Déjame explicarte: hacerlo Blah.valueOf("A")funciona, pero Blah.valueOf("a")no funcionará. Entonces otra vez Blah.valueOf("a".toUpperCase(Locale.ENGLISH))funcionaría.

En Android deberías usar Locale.US, como señala Sulai .

João Portela avatar May 09 '2009 16:05 João Portela