Cast Int à enum en Java

Quelle est la bonne façon de lancer un Int dans un enum en Java étant donné l'enum suivant?

public enum MyEnum
{
    EnumValue1,
    EnumValue2
}


MyEnum enumValue = (MyEnum) x; //Doesn't work???
283
demandé sur trumpetlicks 2011-05-04 09:23:46

15 réponses

Essayer MyEnum.values()[x]x doit être 0 ou 1 , c'est à dire valable ordinal qui enum.

notez qu'en Java les enums sont en fait des classes (et les valeurs d'enum sont donc des objets) et donc vous ne pouvez pas lancer un int ou même Integer sur un enum.

527
répondu Thomas 2016-10-21 13:57:33

MyEnum.values()[x] est une opération coûteuse. Si la performance est un problème, vous pouvez faire quelque chose comme ceci:

public enum MyEnum {
    EnumValue1,
    EnumValue2;

    public static MyEnum fromInteger(int x) {
        switch(x) {
        case 0:
            return EnumValue1;
        case 1:
            return EnumValue2;
        }
        return null;
    }
}
145
répondu Lorenzo Polidori 2012-04-19 09:33:31

si vous voulez donner vos valeurs entières, vous pouvez utiliser une structure comme ci-dessous

public enum A
{
        B(0),
        C(10),
        None(11);
        int id;
        private A(int i){id = i;}

        public int GetID(){return id;}
        public boolean IsEmpty(){return this.equals(A.None);}
        public boolean Compare(int i){return id == i;}
        public static A GetValue(int _id)
        {
            A[] As = A.values();
            for(int i = 0; i < As.length; i++)
            {
                if(As[i].Compare(_id))
                    return As[i];
            }
            return A.None;
        }
}
42
répondu Doctor 2013-01-08 14:36:02

Vous pouvez essayer comme ça.

Créer une Classe avec id d'élément.

      public Enum MyEnum {
        THIS(5),
        THAT(16),
        THE_OTHER(35);

        private int id; // Could be other data type besides int
        private MyEnum(int id) {
            this.id = id;
        }

        public static MyEnum fromId(int id) {
                for (MyEnum type : values()) {
                    if (type.getId() == id) {
                        return type;
                    }
                }
                return null;
            }
      }

maintenant, récupérez cet Enum en utilisant id comme int.

MyEnum myEnum = MyEnum.fromId(5);
23
répondu Piyush Ghediya 2018-05-14 07:31:19

je cache les valeurs et crée une méthode d'accès statique simple:

public static enum EnumAttributeType {
    ENUM_1,
    ENUM_2;
    private static EnumAttributeType[] values = null;
    public static EnumAttributeType fromInt(int i) {
        if(EnumAttributeType.values == null) {
            EnumAttributeType.values = EnumAttributeType.values();
        }
        return EnumAttributeType.values[i];
    }
}
19
répondu ossys 2012-12-18 21:31:53

Java enums n'ont pas le même genre de cartographie enum-to-int qu'ils font en C++.

cela dit, tous les enums ont une méthode values qui retourne un tableau de valeurs possibles d'enum, donc

MyEnum enumValue = MyEnum.values()[x];

devrait marcher. Il est un peu désagréable et il pourrait être préférable de ne pas essayer de convertir de int s à Enum s (ou vice versa) si possible.

9
répondu Cameron Skinner 2011-05-04 05:29:53

Ce n'est pas quelque chose qui est habituellement fait, donc je revienne. Mais cela dit, les opérations fondamentales sont: int --> enum en utilisant EnumType.les valeurs de()[intNum], et enum --> int utilisant enumInst.ordinal.)(

cependant, étant donné que n'importe quelle implémentation de values() n'a pas d'autre choix que de vous donner une copie du tableau (les tableaux java ne sont jamais en lecture seule), vous seriez mieux servi en utilisant un EnumMap pour mettre en cache la cartographie enum --> int.

9
répondu Dilum Ranatunga 2011-05-04 05:32:32

Utiliser MyEnum enumValue = MyEnum.values()[x];

8
répondu w.donahue 2011-10-04 09:58:06

Voici la solution que je prévois d'adopter. Non seulement cela fonctionne avec des entiers non séquentiels, mais cela devrait fonctionner avec tout autre type de données que vous pourriez vouloir utiliser comme id sous-jacent pour vos valeurs enum.

public Enum MyEnum {
    THIS(5),
    THAT(16),
    THE_OTHER(35);

    private int id; // Could be other data type besides int
    private MyEnum(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

    public static Map<Integer, MyEnum> buildMap() {
        Map<Integer, MyEnum> map = new HashMap<Integer, MyEnum>();
        MyEnum[] values = MyEnum.values();
        for (MyEnum value : values) {
            map.put(value.getId(), value);
        }

        return map;
    }
}

j'ai seulement besoin de convertir les id en enums à des moments précis (lors du chargement de données à partir d'un fichier), donc il n'y a aucune raison pour moi de garder la carte en mémoire à tout moment. Si vous avez besoin que la carte soit accessible en tout temps, vous pouvez toujours la mettre en cache membre statique de votre classe D'Enum.

6
répondu jkindwall 2015-05-31 18:01:36

dans le cas où il aide les autres, l'option que je préfère, qui n'est pas énumérée ici, utilise la fonctionnalité de cartes de goyave :

public enum MyEnum {
    OPTION_1(-66),
    OPTION_2(32);

    private int value;
    private MyEnum(final int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }

    private static ImmutableMap<Integer, MyEnum> reverseLookup = 
            Maps.uniqueIndex(Arrays.asList(MyEnum.values())), MyEnum::getValue);

    public static MyEnum fromInt(final int id) {
        return reverseLookup.getOrDefault(id, OPTION_1);
    }
}

avec la valeur par défaut vous pouvez utiliser null , vous pouvez throw IllegalArgumentException ou votre fromInt pourrait retourner un Optional , quel que soit le comportement que vous préférez.

4
répondu Chad Befus 2017-11-16 01:13:19

vous pouvez itérer sur values() de l'enum et comparer la valeur entière de l'enum avec donnée id comme ci-dessous:

public enum  TestEnum {
    None(0),
    Value1(1),
    Value2(2),
    Value3(3),
    Value4(4),
    Value5(5);

    private final int value;
    private TestEnum(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static TestEnum  getEnum(int value){
        for (TestEnum e:TestEnum.values()) {
            if(e.getValue() == value)
                return e;
        }
        return TestEnum.None;//For values out of enum scope
    }
}

et utilisez comme ceci:

TestEnum x = TestEnum.getEnum(4);//Will return TestEnum.Value4

J'espère que cette aide ;)

2
répondu Yashar Aliabasi 2017-06-19 16:45:17

une bonne option est de éviter conversion de int à enum : par exemple, si vous avez besoin de la valeur maximale, vous pouvez comparer X. ordinal () to Y. ordinal () and return x or y correspondingly. (Vous aurez peut-être besoin de réorganiser vos valeurs pour rendre une telle comparaison significative.)

si cela n'est pas possible, je stockerais MyEnum.values() dans un tableau statique.

0
répondu 18446744073709551615 2012-07-02 09:52:43

C'est la même réponse que les médecins mais elle montre comment éliminer le problème avec les matrices mutables. Si vous utilisez ce genre d'approche à cause de la prédiction de branche d'abord si aura très peu à effet zéro et le code entier appelle seulement les valeurs de tableau mutable() la fonction seulement une fois. Comme les deux variables sont statiques, elles ne consommeront pas n * memory pour chaque utilisation de cette énumération.

private static boolean arrayCreated = false;
private static RFMsgType[] ArrayOfValues;

public static RFMsgType GetMsgTypeFromValue(int MessageID) {
    if (arrayCreated == false) {
        ArrayOfValues = RFMsgType.values();
    }

    for (int i = 0; i < ArrayOfValues.length; i++) {
        if (ArrayOfValues[i].MessageIDValue == MessageID) {
            return ArrayOfValues[i];
        }
    }
    return RFMsgType.UNKNOWN;
}
0
répondu Ali Akdurak 2013-05-22 18:55:16
enum MyEnum {
    A(0),
    B(1);
    private final int value;
    private MyEnum(int val) {this.value = value;}
    private static final MyEnum[] values = MyEnum.values();//cache for optimization
    public static final getMyEnum(int value) { 
        try {
            return values[value];//OOB might get triggered
        } catch (ArrayOutOfBoundsException e) {
        } finally {
            return myDefaultEnumValue;
        }
    }
}
0
répondu Zoso 2015-12-14 23:10:59

ceci devrait s'appliquer aux index qui ne sont pas synchronisés avec la question de la valeur ordinale.

package service.manager;

public enum Command {
    PRINT_FOO(0),
    PRINT_BAR(2),
    PRINT_BAZ(3);

    public int intVal;
    Command(int intVal){
        this.intVal = intVal;
    }

    /**
     * Functionality to ascertain an enum from an int
     * The static block initializes the array indexes to correspond with it's according ordinal value
     * Simply use Command.values[index] or get the int value by e.g. Command.PRINT_FOO.intVal;
     * */
    public static Command values[];
    static{
        int maxVal = -1;
        for(Command cmd : Command.values())
            if(maxVal < cmd.intVal)
                maxVal = cmd.intVal;

        values = new Command[maxVal + 1];

        for(Command cmd : Command.values())
            values[cmd.intVal] = cmd;
    }
}
0
répondu Gerrit Brink 2016-04-06 17:18:11