¿Cómo convertir el resultado de cadena de enumeración con toString () anulado de nuevo a enumeración?

StackOverflow https://stackoverflow.com/questions/240122

Pregunta

Dada la siguiente enumeración java:

public enum AgeRange {

   A18TO23 {
        public String toString() {        
            return "18 - 23";
        }
    },
   A24TO29 {
        public String toString() {        
            return "24 - 29";
        }
    },
   A30TO35 {
        public String toString() {        
            return "30 - 35";
        }
    },

}

¿Hay alguna forma de convertir un valor de cadena de " 18 - 23 " al valor de enumeración correspondiente, es decir, AgeRange.A18TO23?

¡Gracias!

¿Fue útil?

Solución

La mejor y más simple manera de hacerlo es así:

public enum AgeRange {
    A18TO23 ("18-23"),
    A24TO29 ("24-29"),
    A30TO35("30-35");

    private String value;

    AgeRange(String value){
        this.value = value;
    }

    public String toString(){
        return value;
    }

    public static AgeRange getByValue(String value){
        for (final AgeRange element : EnumSet.allOf(AgeRange.class)) {
            if (element.toString().equals(value)) {
                return element;
            }
        }
        return null;
    }
}

Luego solo necesitas invocar el método getByValue () con la entrada String .

Otros consejos

Siempre puede crear un mapa de cadena a valor; hágalo de manera estática para que solo tenga que asignarlo una vez, suponiendo que la cadena devuelta permanece igual a lo largo del tiempo. No hay nada incorporado, que yo sepa.

Según el ítem 30 de java efectivo (2ª ed.), puede ser (es mucho más rápido que el bucle)

public enum AgeRange {
       A18TO23("18-23"),
       A24TO29("24-29"),
       A30TO35("30-35");

       private final String value;

       AgeRange(String value){
          this.value = value;
       }

       @Override public String toString(){
           return value;
       }

       private static final Map<String, AgeRange> stringToEnum =
           new HashMap<String, AgeRange>();

       static {
           for (AgeRange r : values()) {
               stringToEnum.put(r.toString(), r);
           }
       }

       public static AgeRange getByValue(String value){
           return stringToEnum.get(value);
       }
}
for (AgeRange ar: EnumSet.allOf(AgeRange)) {
    if (ar.toString().equals(inString)) {
         myAnswer = ar;
         break;
    }
}

¿O algo así? Acaba de escribir, no se han ejecutado a través de un compilador. Perdonar (comentar) los errores tipográficos ...

O usa una lógica como esta para construir un mapa una vez. Evitar la iteración en tiempo de ejecución. Buena idea, Jon.

La clase reemplaza a " toString () " - por lo tanto, para obtener la operación inversa, debe reemplazar valueOf () para traducir la salida de toString () de nuevo a los valores de Enum.

public enum AgeRange {

   A18TO23 {
        public String toString() {        
                return "18 - 23";
        }
        public AgeRange valueOf (Class enumClass, String name) {
                return A18T023
        }
    },

    .
    .
    .
}

Cuidado con el comprador: sin compilar y sin probar ...

El mecanismo para toString () y valueOf () es una parte documentada de API

¿Puedes probar algo como lo siguiente?

static AgeRange fromString(String range) {
    for (AgeRange ageRange : values()) {
        if (range.equals(ageRange.toString())) {
            return ageRange;
        }
    }
    return null;   
}

O, como otros sugirieron, utilizando un enfoque de almacenamiento en caché:

private static Map<String, AgeRange> map;

private static synchronized void registerAgeRange(AgeRange ageRange) {
    if (map == null) {
        map = new HashMap<String, AgeRange>();
    }
    map.put(ageRange.toString(), ageRange);
}

AgeRange() {
    registerAgeRange(this);
}

static AgeRange fromString(String range) {
    return map.get(range);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top