376 votes

Conversion de Int en enum en Java

Quelle est la manière correcte de convertir un Int en un enum en Java avec l'enum suivant ?

public enum MyEnum
{
    EnumValue1,
    EnumValue2
}

MyEnum enumValue = (MyEnum) x; //Doesn't work???

0 votes

@RyuS. Il ne s'agit pas d'un doublon de cette question,

634voto

Thomas Points 35713

Essayez MyEnum.values()[x] donde x doit être 0 o 1 c'est-à-dire un ordinal valide pour cet enum.

Notez qu'en Java, les enums sont en fait des classes (et les valeurs des enums sont donc des objets). int ou même Integer à un enum.

125 votes

+1 : Vous pouvez vouloir mettre en cachette MyEnum.values() car il est coûteux, c'est-à-dire si vous l'appelez des centaines de fois.

7 votes

@PeterLawrey Par souci d'exhaustivité, pouvez-vous expliquer pourquoi il devrait être lent ? Je ne vois aucune raison évidente à cela.

53 votes

@Tarrasch comme les tableaux sont mutables, values() doit retourner une copie du tableau d'éléments au cas où vous le modifieriez. Créer cette copie à chaque fois est relativement coûteux.

182voto

Lorenzo Polidori Points 2903

MyEnum.values()[x] est une opération coûteuse. Si les performances sont 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;
    }
}

49 votes

Si vous voulez éviter la maintenance du commutateur, alors sur la classe d'utilisation : private final MyEnum[] myEnumValues = MyEnum.values() ; Puis utilisation : myEnum = myEnumValues[i] ;

24 votes

@GiliNachum l'a dit d'une manière bizarre, mais le problème avec cette solution est la maintenabilité. Elle va à l'encontre du principe DRY, ce qui signifie que chaque fois que les valeurs de l'énumération sont modifiées (réordonnées, valeur(s) ajoutée(s), valeur(s) supprimée(s)), l'instruction switch doit être simultanément mise à jour. Le commentaire de Gili oblige Java à maintenir la cohérence avec la liste des valeurs de l'énumération, les modifications des valeurs de l'énumération n'affectent pas du tout cette approche.

0 votes

@DandreAllison ce que vous dites est vrai, je viens de proposer une solution alternative possible pour les Enums simples qui ne changent pas souvent. Bien sûr, si vous pouvez mettre en cache les valeurs des Enums dans une propriété finale quelque part, cela évitera le surcoût de maintenance.

52voto

Doctor Points 206

Si vous voulez donner des 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;
        }
}

7 votes

+1 parce qu'il souligne le fait que les valeurs ne doivent pas nécessairement être consécutives.

0 votes

De plus, cela semble être la seule réponse qui fonctionne si vous voulez un ensemble de valeurs entières éparses (ou répétées) plutôt que d'utiliser les ordinaux par défaut de 0..(count-1). Cela peut être important si vous interagissez avec du code existant, par exemple sur un réseau.

0 votes

Il convient de souligner que, comme dans les réponses ci-dessus, la mise en cache du résultat de values() est probablement utile, afin d'éviter une allocation de mémoire et une copie de tableau à chaque fois que vous l'invoquez.

10voto

Dilum Ranatunga Points 7677

Ce n'est pas quelque chose qui se fait habituellement, alors j'y réfléchirais. Cela dit, les opérations fondamentales sont les suivantes : int --> enum using EnumType.values()[intNum] et enum --> int en utilisant enumInst.ordinal() .

Cependant, comme toute mise en œuvre 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), il serait plus judicieux d'utiliser un tableau de type EnumMap pour mettre en cache le mapping enum --> int.

2 votes

Re "Ce n'est pas quelque chose qui se fait habituellement" : Cas courant où c'est utile : l'enum correspond à des valeurs int stockées dans une base de données.

0 votes

@ToolmakerSteve vous avez tout à fait raison de dire que les mappings sont nécessaires. Mais voudriez-vous laisser ce type d'encodage à un mappeur O-R ou à une boîte à outils/une bibliothèque ?

8voto

w.donahue Points 4051

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

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