Dis que j'ai une énumération qui est juste
public enum Blah {
A, B, C, D
}
et je voudrais trouver la valeur énumérée d'une chaîne, par exemple "A"
qui serait Blah.A
. Comment serait-il possible de faire cela?
Est-ce Enum.valueOf()
la méthode dont j'ai besoin? Si oui, comment pourrais-je l'utiliser?
Blah.valueOf("A")
méthode est sensible à la casse et ne tolère pas les espaces étrangers, d'où la solution alternative proposée ci-dessous par @ JoséMi.toString()
valeur, non, je ne dirais pas cela.name()
vous obtiendra le nom réel défini de la constante enum à moins que vous ne le remplaciez.enum Blah {...}
définition actuelle ne doit pas essayer de déclarer son proprevalues
nivaluesOf
. C'est comme comment vous pouvez écrire "AnyTypeName.class" même si vous n'avez jamais réellement déclaré une variable membre "class"; le compilateur fait tout juste fonctionner. (Cette réponse peut ne plus vous être utile 3 mois plus tard, mais juste au cas où.)Une autre solution si le texte n'est pas le même que la valeur d'énumération:
la source
throw new IllegalArgumentException("No constant with text " + text + " found")
serait mieux quereturn null
.Voici un utilitaire astucieux que j'utilise:
Ensuite, dans ma classe d'énumération, j'ai généralement ceci pour économiser de la frappe:
Si vos énumérations ne sont pas toutes des majuscules, modifiez simplement le
Enum.valueOf
ligne.Dommage que je ne peux pas utiliser
T.class
pourEnum.valueOf
queT
est effacé.la source
Utilisez le modèle de Joshua Bloch, Java efficace :
(simplifié par souci de concision)
Regarde aussi:
Exemple Oracle Java utilisant Enum et Map of instances
Ordre d'exécution des blocs statiques dans un type Enum
Comment puis-je rechercher une énumération Java à partir de sa valeur de chaîne
la source
Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))
je recommande également de remplacer toString () (transmis via le constructeur) et de l'utiliser à la place du nom, surtout si l'énumération est associée à des données sérialisables car cela vous permet de contrôler le boîtier sans donner Sonar un ajustement.unmodifiableMap
toute façon, il n'y a aucun avantage à commencer par unConcurrentHashMap
. Utilisez simplement unHashMap
. (Si vous avez de la goyave,ImmutableMap
je le recommanderais à la place!)ConcurrentHashMap
ici, où la carte n'est jamais modifiée après l'initialisation. Par conséquent, même par exemple, l'exemple dans le JLS lui-même utilise un régulierHashMap
.Vous devez également être prudent avec votre cas. Permettez-moi de vous expliquer: faire des
Blah.valueOf("A")
travaux, maisBlah.valueOf("a")
ne fonctionnera pas. Là encore, çaBlah.valueOf("a".toUpperCase(Locale.ENGLISH))
marcherait.modifier
Changé
toUpperCase
entoUpperCase(Locale.ENGLISH)
basé sur tc. commentaire et les documents javaedit2 Sur android, vous devriez utiliser
Locale.US
, comme le souligne sulai .la source
Locale.US
entrées / sorties lisibles par machine.Voici une méthode qui peut le faire pour n'importe quel Enum et ne respecte pas la casse.
la source
equalsIgnoreCase
c'est la voie à suivre. +1L'utilisation
Blah.valueOf(string)
est la meilleure, mais vous pouvez également l'utiliserEnum.valueOf(Blah.class, string)
.la source
Dans Java 8 ou version ultérieure, à l'aide de Streams :
la source
Si vous ne voulez pas écrire votre propre utilitaire, utilisez Google goyave bibliothèque:
Contrairement à la fonction java intégrée, il vous permet de vérifier si A est présent dans Blah et ne lève pas d'exception.
la source
Mes 2 cents ici: utiliser Java8 Streams + vérifier une chaîne exacte:
** ÉDITER **
Renommée la fonction pour la
fromString()
nommer en utilisant cette convention, vous obtiendrez certains avantages du langage Java lui-même; par exemple:la source
switch
blocs plus lisibles , vous pouvez le faire à la.orElse(null)
place de.orElseThrow()
afin de pouvoir coder la levée d'exception dans ladefault
clause - et inclure des informations plus utiles si nécessaire. Et pour le rendre plus clément, vous pouvez utiliserv -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
Optional
fromfindFirst()
, permettant à l'utilisateur de décider s'il veut.orElse(null)
,orElseThrow()
ou quoi que ce soit ....public static MyEnum valueOf(String)
est en fait une erreur de compilation, car elle est la même que celle définie implicitement, donc l'ancienne version de votre réponse est en fait meilleure. ( jls , ideone )Vous devrez peut-être:
Encore un ajout:
Cela vous renverra la valeur par un nom d'énumération chaîne. Par exemple, si vous fournissez "PERSON" dans le fromEnumName, cela vous renverra la valeur d'énum ie "Personne"
la source
Une autre façon de le faire en utilisant la méthode statique implicite
name()
d'Enum. nom renverra la chaîne exacte utilisée pour créer cette énumération qui peut être utilisée pour vérifier la chaîne fournie:Essai:
System.out.println(Blah.getEnum("B").name());
inspiration: 10 exemples d'Enum en Java
la source
valueOf
fait pour vous. Cette méthode statique n'offre rien de plus, exception et tout. Les constructions if / else sont alors très dangereuses ... toute nouvelle constante enum ajoutée entraînera la rupture de cette méthode sans changement.name()
n'est pas statique.Solution utilisant les bibliothèques Guava. La méthode getPlanet () n'est pas sensible à la casse, donc getPlanet ("MerCUrY") renverra Planet.MERCURY.
la source
Pour compléter les réponses précédentes et répondre à certaines des discussions sur les valeurs NULL et NPE, j'utilise les options de la goyave pour gérer les cas absents / non valides. Cela fonctionne très bien pour l'analyse d'URI / paramètres.
Pour ceux qui ne le savent pas, voici quelques informations supplémentaires sur la façon d'éviter le null avec Facultatif: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional
la source
Dans Java 8, le modèle de carte statique est encore plus facile et est ma méthode préférée. Si vous souhaitez utiliser l'énumération avec Jackson, vous pouvez remplacer toString et l'utiliser à la place de nom, puis annoter avec
@JsonValue
la source
la source
Méthode O (1) inspirée du code généré par l'épargne qui utilise une table de hachage.
la source
Enum est très utile, j'ai beaucoup utilisé
Enum
pour ajouter une description de certains champs dans différentes langues, comme l'exemple suivant:Et puis vous pouvez récupérer la description dynamiquement en fonction du code de langue transmis à la
getDescription(String lang)
méthode, par exemple:la source
Qu'en est-il de?
la source
java.lang.Enum
définit plusieurs méthodes utiles, disponibles pour tous les types d'énumération en Java:name()
méthode pour obtenir le nom des constantes Enum. Le littéral de chaîne utilisé pour écrire les constantes enum est leur nom.values()
méthode peut être utilisée pour obtenir un tableau de toutes les constantes Enum d'un type Enum.valueOf()
méthode pour convertir n'importe quelle constante String en Enum en Java, comme indiqué ci-dessous.Dans cet extrait de code, la
valueOf()
méthode retourne une constante Enum Gender.MALE, appelant le nom sur ce retour"MALE"
.la source
La bibliothèque commons-lang d' Apache a une fonction statique org.apache.commons.lang3.EnumUtils.getEnum qui mappera une chaîne à votre type Enum. Même réponse que Geoffreys, mais pourquoi lancer la vôtre quand elle est déjà dans la nature.
la source
Ajout à la réponse la mieux notée, avec un utilitaire utile ...
valueOf()
lève deux exceptions différentes dans les cas où il n'aime pas son entrée.IllegalArgumentException
NullPointerExeption
Si vos exigences sont telles que vous n'avez aucune garantie que votre chaîne correspondra définitivement à une valeur d'énumération, par exemple si les données de chaîne proviennent d'une base de données et peuvent contenir une ancienne version de l'énumération, vous devrez les gérer souvent...
Voici donc une méthode réutilisable que j'ai écrite qui nous permet de définir une énumération par défaut à renvoyer si la chaîne que nous transmettons ne correspond pas.
Utilisez-le comme ceci:
la source
Comme une
switch
version-n'a pas encore été mentionnée, je l'introduis (en réutilisant l'énumération OP):Comme cela ne donne aucune valeur supplémentaire à la
valueOf(String name)
méthode, il est logique de définir une méthode supplémentaire si nous voulons avoir un comportement différent. Si nous ne voulons pas augmenter un,IllegalArgumentException
nous pouvons changer l'implémentation en:En fournissant une valeur par défaut, nous conservons le contrat de
Enum.valueOf(String name)
sans en lancer unIllegalArgumentException
de cette manière qui en aucun casnull
n'est retourné. Par conséquent, nous lançons unNullPointerException
si le nom estnull
et en cas dedefault
sidefaultValue
estnull
. Voilà comment çavalueOfOrDefault
marche.Cette approche adopte la conception de
Map
-Interface qui fournit une méthode àMap.getOrDefault(Object key, V defaultValue)
partir de Java 8.la source
Un autre utilitaire capturant en sens inverse. Utiliser une valeur qui identifie cet Enum, pas à partir de son nom.
Exemple:
EnumUtil.from(Foo.class, "drei")
renvoieFoo.THREE
, car il utiliseragetValue
pour faire correspondre "drei", qui est une méthode publique unique, non finale et non statique dans Foo. Dans le cas Foo a plus que la méthode publique, pas définitive et non statique, par exemple,getTranslate
qui renvoie « drei », l'autre méthode peut être utilisée:EnumUtil.from(Foo.class, "drei", "getTranslate")
.la source
Kotlin Solution
Créez un poste, puis appelez
valueOf<MyEnum>("value")
. Si le type n'est pas valide, vous obtiendrez null et devrez le gérerAlternativement, vous pouvez définir une valeur par défaut, appeler
valueOf<MyEnum>("value", MyEnum.FALLBACK)
et éviter une réponse nulle. Vous pouvez étendre votre énumération spécifique pour que la valeur par défaut soit automatiqueOu si vous voulez les deux, faites le second:
la source
J'aime utiliser ce genre de processus pour analyser les commandes sous forme de chaînes dans les énumérations. J'ai normalement l'une des énumérations comme "inconnue", donc il est utile de la renvoyer lorsque les autres ne sont pas trouvées (même sur une base insensible à la casse) plutôt que null (ce qui signifie qu'il n'y a pas de valeur). C'est pourquoi j'utilise cette approche.
la source
Le moyen le plus rapide pour obtenir le nom d'énumération est de créer une carte du texte et de la valeur d'énumération au démarrage de l'application, et pour obtenir le nom, appelez la fonction Blah.getEnumName ():
la source