2012-04-17 97 views
10

Tengo dos enumeraciones diferentes y quiero poder mostrar si una cadena dada es parte de una colección enum. este es mi código:¿Cómo comprobar si una cadena dada es una parte de cualquier Enum en Java?

public class Check { 
    public enum Filter{SIZE, DATE, NAME}; 
    public enum Action{COPY, DELETE, REMOVE}; 

    public boolean isInEnum(String value, Enum e){ 
     // check if string value is a part of a given enum 
     return false; 
    } 

    public void main(){ 
     String filter = "SIZE"; 
     String action = "DELETE"; 
       // check the strings 
     isInEnum(filter, Filter); 
     isInEnum(action, Action); 
    } 
} 

Eclipse dice que en las dos últimas líneas de "filtro no se puede resolver de una variable", pero aparte de eso, parece que el parámetro de enumeración en la función "isInEnum" está mal .

Algo está muy mal aquí ¿alguien puede ayudar?

+0

Tienes ese derecho :) enum es solo una clase normal, no puedes mencionar su nombre así. Enum mebers son instancias de su enumeración, no la enumeración como un todo. –

Respuesta

20

La manera más simple (y por lo general más eficiente) es el siguiente:

public <E extends Enum<E>> boolean isInEnum(String value, Class<E> enumClass) { 
    for (E e : enumClass.getEnumConstants()) { 
    if(e.name().equals(value)) { return true; } 
    } 
    return false; 
} 

y luego se llama a isInEnum(filter, Filter.class).

+0

¿Qué tal 'enumClass.getMethod (" valueOf ", String.class) .invoke (null, value)'? –

+1

esto hizo el truco pero la sintaxis es una locura .. necesita aprender un poco acerca de esos genéricos – Tom

+1

@MarkoTopolnik por qué usar Reflection cuando está recorriendo los elementos de todos modos y puede usar 'e.valueOf (value)' en su lugar. También tenga en cuenta que al usar valueOf tiene que capturar 'IllegalArgumentException' si el nombre no existe y' NullPointerException' si la cadena es nula – Ozzy

0

Evite utilizar un bucle para realizar la validación.

Yo sugeriría usar valueOf. Este método está incorporado en las enumeraciones y podría considerarse para la optimización del tiempo de compilación.

Esto sería similar a implementar un Map<String,EnumType> estático para optimizar la búsqueda, otra consideración que puede tomar.

El inconveniente es que tendría que usar el mecanismo de manejo de excepciones para capturar un valor que no sea enum.

Ejemplo

public enum DataType { 
    //... 
    static public boolean has(String value) { 
    if (value== null) return false; 
    try { 
     // In this implementation - I want to ignore the case 
     // if you want otherwise ... remove .toUpperCase() 
     return valueOf(value.toUpperCase()); 
    } catch (IllegalArgumentException x) { 
     // the uggly part ... 
     return false; 
    } 
    } 
} 

También tenga en cuenta que con la implementación del tipo anterior, su código es mucho más limpio al llamar. Su principal ahora se vería así:

public void main(){ 
    String filter = "SIZE"; 
    String action = "DELETE"; 

    // ... 

    if (Filter.has(filter) && Action.has(action)) { 
     // Appropriate action 
    } 
} 

Luego, la otra opción mencionada es utilizar un Mapa estático. Puede emplear dicho enfoque para almacenar en caché todo tipo de indexación en función de otras propiedades también. En el ejemplo siguiente, permito que cada valor enum tenga una lista de nombres de alias. El índice de búsqueda en este caso será insensible a mayúsculas y minúsculas, forzando a mayúsculas.

public enum Command { 
    DELETE("del","rm","remove"), 
    COPY("cp"), 
    DIR("ls"); 

    private static final Map<String,Command> ALIAS_MAP = new HashMap<String,Command>(); 
    static { 
    for (Command type:Command.values()) { 
     ALIAS_MAP.put(type.getKey().toUpper(),type); 
     for (String alias:type.aliases) ALIAS_MAP.put(alias.toUpper(),type); 
    } 
    } 

    static public boolean has(String value) { 
    return ALIAS_MAP.containsKey(value.toUpper()); 
    } 

    static public Command fromString(String value) { 
    if (value == null) throw new NullPointerException("alias null"); 
    Command command = ALIAS_MAP.get(value); 
    if (command == null) throw new IllegalArgumentException("Not an alias: "+value); 
    return command; 
    } 

    private List<String> aliases; 
    private Command(String... aliases) { 
    this.aliases = Arrays.asList(aliases); 
    } 
} 
+0

Tenga en cuenta las publicaciones de comentarios sobre la sobrecarga de las excepciones. Estaban escondidos cuando publiqué por primera vez. – YoYo

+0

Estaba viendo otro tema similar. Un usuario mencionó que en tal caso el compilador JIT optimizaría la sobrecarga de excepción. La sobrecarga solo se nota durante la depuración debido a toda la instrumentación. – YoYo

4

Aquí hay una versión de Java 8/streams de la respuesta de Louis Wasserman. (También se puede poner este método directamente en la clase Enum, y quitar uno de los parámetros)

public boolean isInEnum(String value, Class<E> enumClass) { 
    return Arrays.stream(enumClass.getEnumConstants()).anyMatch(e -> e.name().equals(value)); 
    } 
2

no tengo suficientes puntos para comentar sobre la respuesta de Simón Torre directamente, pero aquí es el método para la segunda forma mencionó que va directamente en la clase de enumeración en sí:

public static boolean isInEnum(String value) { 
    return Arrays.stream(EnumClassNameGoesHere.values()).anyMatch(e -> e.name().equals(value)); 
} 
8

Si no les importa usar Apache Commons biblioteca lang3 se puede utilizar el siguiente código:

EnumUtils.isValidEnum(Filter.class, filter) 

De acuerdo con el docs:

Este método difiere de Enum.valueOf (java.lang.Class, java.lang.String), ya que no produce una excepción para un nombre de enumeración no válido.

Cuestiones relacionadas