119 votes

Mapper commodément entre enum et int / String

Lorsque l'on travaille avec des variables et des paramètres qui ne peuvent prendre qu'un nombre fini de valeurs, j'essaie de toujours utiliser Java enum, comme dans

public enum BonusType {
  MONTHLY, YEARLY, ONE_OFF
}

Tant que je reste dans mon code, cela fonctionne bien. Cependant, j'ai souvent besoin de faire l'interface avec un autre code qui utilise la plaine int (ou String) des valeurs pour le même but, ou j'ai besoin de lire/écrire dans une base de données où les données sont stockées comme un nombre ou une chaîne.

Dans ce cas, j'aimerais avoir un moyen commode d'associer à chaque valeur d'enum avec un entier, tel que je peux le convertir à la fois des moyens (en d'autres mots, j'ai besoin d'un "réversible " enum").

Allant de enum type int est facile:

public enum BonusType {
  public final int id;

  BonusType(int id) {
    this.id = id;
  }
  MONTHLY(1), YEARLY(2), ONE_OFF(3);
}

Ensuite, je peux accéder à l'int valeur BonusType x = MONTHLY; int id = x.id;.

Cependant, je ne vois pas de bonne façon pour l'inverse, c'est à dire en allant de int enum. Idéalement, quelque chose comme

BonusType bt = BonusType.getById(2); 

Les seules solutions que je pouvais venir sont:

  • Mettre une méthode de recherche dans l'enum, qui utilise BonusType.values() de remplir une carte "int -> enum", puis les caches et les utilise pour effectuer des recherches. Mais je dois copier cette méthode de manière identique dans chaque enum j'utilise :-(.
  • Mettre la méthode de recherche dans une statique de la classe utilitaire. Ensuite, j'ai seulement besoin d'une "recherche" de la méthode, mais j'ai dû jouer avec la réflexion pour faire fonctionner l'arbitraire d'un enum.

Les deux méthodes semblent terriblement maladroite pour un simple (?) problème.

D'autres idées/idées?

342voto

aioobe Points 158466

enum → int

yourEnum.ordinal()

int → enum

EnumType.values()[someInt]

String → enum

EnumType.valueOf(yourString)

enum → Chaîne

yourEnum.name()

D'un côté-note:
Comme vous le précisez à juste titre, l' ordinal() peut être "instable" à partir d'une version à l'autre. C'est la raison exacte pour laquelle j'ai toujours stocker les constantes chaînes de caractères dans mes bases de données. (En fait, lors de l'utilisation de MySql, je les stocker en tant que MySql enums!)

39voto

Jeff Points 1780

http://www.javaspecialists.co.za/Archive/Issue113.html

La solution commence par semblable à la vôtre avec une valeur int dans le cadre de la définition de l’enum. Il continue alors de créer un utilitaire de recherche basée sur les génériques :

Cette solution est agréable et ne nécessite pas de « jongler avec la réflexion », parce qu’elle est fondée sur le fait que tous les types enum héritent implicitement l’interface Enum.

32voto

melqkiades Points 171

J’ai trouvé ceci sur le web, il a été très utile et simple à mettre en œuvre. Cette solution n’était pas faite par moi

http://www.ajaxonomy.com/2007/Java/Making-the-most-of-Java-50-enum-Tricks

}

5voto

Alastair McCormack Points 1727
<h2>org.apache.commons.lang.enums.ValuedEnum ;<p>Pour me sauver des charges d’écriture de code réutilisable ou dupliquer le code pour chaque Enum, j’avais l’habitude de Apache Commons Lang <code></code> à la place.</p><p><strong>Définition</strong>:</p><pre><code></code></pre><p><strong>Utilisation :</strong></p><p><strong>int -> ValuedEnum :</strong></p><pre><code></code></pre></h2>

3voto

extraneon Points 13362

Vous pourriez peut-être utiliser quelque chose comme

Cela réduirait la nécessité d’une réflexion dans votre classe d’utilitaire.

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