Je voudrais rechercher une énumération à partir de sa valeur de chaîne (ou éventuellement de toute autre valeur). J'ai essayé le code suivant mais il n'autorise pas la statique dans les initialiseurs. Y a-t-il un moyen simple?
public enum Verbosity {
BRIEF, NORMAL, FULL;
private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();
private Verbosity() {
stringMap.put(this.toString(), this);
}
public static Verbosity getVerbosity(String key) {
return stringMap.get(key);
}
};
stringMap
initialisation). La solution habituelle consiste à utiliser une classe imbriquée.Réponses:
Utilisez la
valueOf
méthode qui est automatiquement créée pour chaque Enum.Pour les valeurs arbitraires, commencez par:
Ne passez à l'implémentation de Map que si votre profileur vous le demande.
Je sais que cela itère sur toutes les valeurs, mais avec seulement 3 valeurs d'énumération, cela ne vaut guère aucun autre effort, en fait à moins que vous n'ayez beaucoup de valeurs, je ne me soucierais pas d'une carte, ce sera assez rapide.
la source
IllegalArgumentException
au lieu de renvoyer null ( c'est- à- dire lorsqu'aucune correspondance n'est trouvée) - c'est ainsi que le JDK leEnum.valueOf(..)
fait, de toute façon.Tu es proche. Pour les valeurs arbitraires, essayez quelque chose comme ce qui suit:
la source
HashMap<>
pour stocker les énumérations s'est avéré être plus de 40% plus rapide qu'une boucle de plancher.avec Java 8, vous pouvez réaliser de cette manière:
la source
null
. Mais cela dépend aussi du cas d'utilisationLa réponse de @ Lyle est plutôt dangereuse et je l'ai vu ne pas fonctionner en particulier si vous faites de l'énumération une classe interne statique. Au lieu de cela, j'ai utilisé quelque chose comme celui-ci qui chargera les cartes BootstrapSingleton avant les énumérations.
Modifier cela ne devrait plus être un problème avec les JVM modernes (JVM 1.6 ou supérieur) mais je pense qu'il y a encore des problèmes avec JRebel mais je n'ai pas eu l'occasion de le tester à nouveau .
Chargez-moi d'abord:
Maintenant, chargez-le dans le constructeur enum:
Si vous avez une énumération interne, vous pouvez simplement définir la carte au-dessus de la définition d'énumération et cela (en théorie) devrait être chargé avant.
la source
Et vous ne pouvez pas utiliser valueOf () ?
Edit: Btw, rien ne vous empêche d'utiliser static {} dans une énumération.
la source
valueOf
sur la classe enum, vous n'avez donc pas besoin de spécifier la classe enumClass
.Au cas où cela aiderait les autres, l'option que je préfère, qui n'est pas répertoriée ici, utilise la fonctionnalité Cartes de Guava :
Avec la valeur par défaut, vous pouvez utiliser
null
, vous pouvezthrow IllegalArgumentException
ou vousfromString
pouvez retourner unOptional
comportement, quel que soit le comportement que vous préférez.la source
depuis java 8 vous pouvez initialiser la carte en une seule ligne et sans bloc statique
la source
Function.identity()
auparavant, je la trouve beaucoup plus attrayante textuellement quee -> e
.Peut-être, jetez un œil à ceci. Cela fonctionne pour moi. Le but de ceci est de rechercher 'RED' avec '/ red_color'. Déclarer a
static map
et ne charger leenum
s qu'une seule fois apporterait des avantages en termes de performances si lesenum
s sont nombreux.Veuillez donner votre avis.
la source
Vous pouvez définir votre Enum comme le code suivant:
Voir le lien suivant pour plus de précisions
la source
Si vous voulez une valeur par défaut et ne voulez pas créer de mappes de recherche, vous pouvez créer une méthode statique pour gérer cela. Cet exemple gère également les recherches où le nom attendu commencerait par un nombre.
Si vous en avez besoin sur une valeur secondaire, vous devez simplement créer la carte de recherche en premier, comme dans certaines des autres réponses.
la source
}
la source
Vous pouvez utiliser la
Enum::valueOf()
fonction comme suggéré par Gareth Davis & Brad Mace ci-dessus, mais assurez-vous de gérer leIllegalArgumentException
qui serait lancé si la chaîne utilisée n'est pas présente dans l'énumération.la source