J'ai le type d'énumération ReportTypeEnum
qui est transmis entre les méthodes dans toutes mes classes, mais je dois ensuite le passer sur l'URL, donc j'utilise la méthode ordinale pour obtenir la valeur int. Après l'avoir obtenu dans mon autre page JSP, je dois le reconvertir en un ReportTypeEnum
afin de pouvoir continuer à le transmettre.
Comment puis-je convertir l'ordinal en ReportTypeEnum
?
Utilisation de Java 6 SE.
Réponses:
Pour convertir un ordinal en sa représentation enum, vous pouvez procéder comme suit:
Veuillez noter les limites du tableau.
Notez que chaque appel à
values()
renvoie un tableau nouvellement cloné, ce qui peut avoir un impact négatif sur les performances. Vous souhaiterez peut-être mettre en cache le tableau s'il doit être appelé souvent.Exemple de code sur la façon de mettre en cache
values()
.Cette réponse a été modifiée pour inclure les commentaires fournis dans les commentaires
la source
C'est presque certainement une mauvaise idée . Certes, si l'ordinal est de facto persistant (par exemple, parce que quelqu'un a mis en signet l'URL) - cela signifie que vous devez toujours conserver l'
enum
ordre à l'avenir, ce qui peut ne pas être évident pour les responsables du code sur la ligne.Pourquoi ne pas encoder l'
enum
utilisationmyEnumValue.name()
(et décoder viaReportTypeEnum.valueOf(s)
) à la place?la source
value
au début ou à sa position alphabétique / logique correcte. (Par logique, je veux dire par exemple que lesTimeUnit
valeurs ont une position logique)Si je vais utiliser
values()
beaucoup:Pendant ce temps où.java:
Faites attention aux limites de votre tableau.
la source
Suit.values[0] = Suit.Diamonds;
quelque part dans votre code. Idéalement, cela ne se produira jamais, mais le principe général de ne pas exposer les champs mutables est toujours valable. Pour cette approche, envisagez d'utiliserCollections.unmodifiableList
ou similaire à la place.Suit values[]
directement ou indirectement (comment cela a été mentionnégetValues()
), je travaille avec une méthode publique où laordinal
valeur doit être envoyée comment un argument et renvoyer laSuit
représentationSuit values[]
. Le point ici (la tuile de la question depuis le début) était de créer un type d'énumération à partir d'un ordinal d'énumérationJe suis d'accord avec la plupart des gens que l'utilisation de l'ordinal est probablement une mauvaise idée. Je résout généralement ce problème en donnant à l'énumération un constructeur privé qui peut prendre par exemple une valeur DB, puis créer une
fromDbValue
fonction statique similaire à celle de la réponse de Jan.Vous pouvez maintenant modifier l'ordre sans modifier la recherche et vice versa.
la source
Vous pouvez utiliser une table de recherche statique:
la source
0...(n-1)
, alors un tableau est moins de code et plus lisible aussi; l'amélioration des performances n'est qu'un bonus.private static final Suit[] VALUES = values();
etpublic Suit fromOrdinal(int ordinal) { return VALUES[ordinal]; }
. Avantage supplémentaire: se bloque immédiatement sur les ordinaux invalides, plutôt que de retourner silencieusement null. (Pas toujours un avantage. Mais souvent.)C'est ce que j'utilise. Je ne prétends pas que c'est beaucoup moins "efficace" que les solutions plus simples ci-dessus. Ce qu'il fait est de fournir un message d'exception beaucoup plus clair que "ArrayIndexOutOfBounds" lorsqu'une valeur ordinale non valide est utilisée dans la solution ci-dessus.
Il utilise le fait que javadoc EnumSet spécifie que l'itérateur renvoie les éléments dans leur ordre naturel. Il y a une affirmation si ce n'est pas correct.
Le test JUnit4 montre comment il est utilisé.
la source
Voici ce que je fais sur Android avec Proguard:
c'est court et je n'ai pas besoin de m'inquiéter d'avoir une exception dans Proguard
la source
Vous pouvez définir une méthode simple comme:
Et utilisez-le comme:
la source
la classe de test
J'apprécie que vous partagiez avec nous si vous avez un code plus efficace, mon énumération est énorme et constamment appelée des milliers de fois.
la source
Donc, une façon est de faire
ExampleEnum valueOfOrdinal = ExampleEnum.values()[ordinal];
ce qui fonctionne et c'est facile, cependant, comme mentionné précédemment,ExampleEnum.values()
retourne un nouveau tableau cloné pour chaque appel. Cela peut être inutilement coûteux. Nous pouvons résoudre ce problème en mettant le tableau en cache de cette façonExampleEnum[] values = values()
. Il est également "dangereux" de permettre à notre tableau mis en cache d'être modifié. Quelqu'un pourrait écrireExampleEnum.values[0] = ExampleEnum.type2;
Donc je le rendrais privé avec une méthode d'accesseur qui ne fait pas de copie supplémentaire.Vous utiliseriez
ExampleEnum.value(ordinal)
pour obtenir la valeur d'énumération associée àordinal
la source
Chaque enum a un nom (), qui donne une chaîne avec le nom du membre enum.
Étant donné
enum Suit{Heart, Spade, Club, Diamond}
,Suit.Heart.name()
donneraHeart
.Chaque énumération a un
valueOf()
méthode, qui prend un type d'énumération et une chaîne, pour effectuer l'opération inverse:Enum.valueOf(Suit.class, "Heart")
retourneSuit.Heart
.Pourquoi quelqu'un utiliserait des ordinaux me dépasse. Cela peut être plus rapide de nanosecondes, mais ce n'est pas sûr, si les membres de l'énumération changent, car un autre développeur peut ne pas être au courant qu'un code s'appuie sur des valeurs ordinales (en particulier dans la page JSP citée dans la question, la surcharge du réseau et de la base de données domine complètement le temps, sans utiliser un entier sur une chaîne).
la source