94 votes

Itérer les valeurs enum en utilisant des génériques java

J'essaie de trouver un moyen pour effectuer une itération à travers une énumération de valeurs lors de l'utilisation des médicaments génériques. Vous ne savez pas comment faire ou si c'est possible.

Le code suivant illustre ce que je veux faire. Notez que le code T. les valeurs de() n'est pas valide dans le code suivant.

public class Filter<T> {
    private List<T> availableOptions = new ArrayList<T>();
    private T selectedOption;

    public Filter(T selectedOption) {
        this.selectedOption = selectedOption;
        for (T option : T.values()) {  // INVALID CODE
            availableOptions.add(option);
        }
    }
}

Voici comment je l'instancier un objet de Filtre:

Filter<TimePeriod> filter = new Filter<TimePeriod>(TimePeriod.ALL);

L'enum est définie comme suit:

public enum TimePeriod {
    ALL("All"), 
    FUTURE("Future"), 
    NEXT7DAYS("Next 7 Days"), 
    NEXT14DAYS("Next 14 Days"), 
    NEXT30DAYS("Next 30 Days"), 
    PAST("Past"),
    LAST7DAYS("Last 7 Days"), 
    LAST14DAYS("Last 14 Days"),
    LAST30DAYS("Last 30 Days"); 

    private final String name;

    private TimePeriod(String name) {
        this.name = name;
    }

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

Je me rends compte qu'il ne pourrait pas faire de sens pour copier un enum valeurs à une liste, mais je suis en utilisant une bibliothèque qui a besoin d'une liste de valeurs en entrée et ne fonctionne pas avec les énumérations.


EDIT 2/5/2010:

La plupart des réponses proposées sont très similaires et suggère de faire quelque chose comme ceci:

class Filter<T extends Enum<T>> {
    private List<T> availableOptions = new ArrayList<T>();
    private T selectedOption;

    public Filter(T selectedOption) {
        Class<T> clazz = (Class<T>) selectedOption.getClass();
        for (T option : clazz.getEnumConstants()) {
            availableOptions.add(option);
        }
    }
}

Ce serait excellent travail, si je peux être sûr que selectedOption a une valeur non nulle. Malheureusement, dans mon cas d'utilisation, cette valeur est souvent nulle, comme il y a un public Filtre() n-arg constructeur ainsi. Cela signifie que je ne peux pas faire un selectedOption.getClass() sans obtenir de NPE. Cette classe de filtre gère une liste d'options disponibles les options est sélectionnée. Lorsque rien n'est sélectionné, selectedOption est null.

La seule chose que je peux penser pour résoudre ce problème est de passer dans une Classe dans le constructeur. Donc quelque chose comme ceci:

class Filter<T extends Enum<T>> {
    private List<T> availableOptions = new ArrayList<T>();
    private T selectedOption;

    public Filter(Class<T> clazz) {
        this(clazz,null);
    }

    public Filter(Class<T> clazz, T selectedOption) {
        this.selectedOption = selectedOption;
        for (T option : clazz.getEnumConstants()) {
            availableOptions.add(option);
        }
    }
}

Toutes les idées sur la façon de le faire sans avoir besoin d'une Classe supplémentaire paramètre dans le constructeur?

139voto

Thirler Points 6222

C'est un problème difficile en effet. Une des choses que vous devez faire est de dire à Java que vous utilisez un enum. En déclarant que vous étendez la classe Enum pour vos génériques. Cependant, cette classe n'a pas la fonction values (). Vous devez donc suivre le cours pour lequel vous pouvez obtenir les valeurs.

L'exemple suivant devrait vous aider à résoudre votre problème:

 public <T extends Enum<T>> void enumValues(Class<T> enumType) {
        for (T c : enumType.getEnumConstants()) {
             System.out.println(c.name());
        }
}
 

19voto

Miserable Variable Points 17515

Une autre option consiste à utiliser EnumSet:

 class PrintEnumConsants {

    static <E extends Enum <E>> void foo(Class<E> elemType) {
        for (E e : java.util.EnumSet.allOf(elemType)) {
            System.out.println(e);
        }
    }

    enum Color{RED,YELLOW,BLUE};
    public static void main(String[] args) {
        foo(Color.class);
    } 

}
 

5voto

Bozho Points 273663

En utilisant un casting dangereux:

 class Filter<T extends Enum<T>> {
    private List<T> availableOptions = new ArrayList<T>();
    private T selectedOption;

    public Filter(T selectedOption) {
        Class<T> clazz = (Class<T>) selectedOption.getClass();
        for (T option : clazz.getEnumConstants()) {
            availableOptions.add(option);
        }
    }
}
 

1voto

NawaMan Points 10266

Si vous êtes sûr que selectedOption du constructeur Filter(T selectedOption) n'est pas nul. Vous pouvez utiliser la réflexion. Comme ça.

 public class Filter<T> {
    private List<T> availableOptions = new ArrayList<T>();
    private T selectedOption;

    public Filter(T selectedOption) {
        this.selectedOption = selectedOption;
        for (T option :  

J'espère que cela t'aides.

0voto

Steve McLeod Points 19016

Le problème fondamental est que vous devez convertir un tableau en liste, n'est-ce pas? Vous pouvez le faire en utilisant un type spécifique (TimePeriod au lieu de T) et le code suivant.

Alors utilisez quelque chose comme ça:

 List<TimePeriod> list = new ArrayList<TimePeriod>();
list.addAll(Arrays.asList(sizes));
 

Maintenant, vous pouvez passer liste dans n'importe quelle méthode qui veut une liste.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X