Insensible à la casse d'une chaîne à une enum de Java
Java
fournit un valueOf()
méthode pour chaque Enum<T>
objet, donc, étant donné un enum
comme
public enum Day {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
on peut faire une recherche comme
Day day = Day.valueOf("Monday");
Si la chaîne passée à valueOf()
ne correspond pas (sensible à la casse) un Day
valeur, une IllegalArgumentException
est levée.
De faire une comparaison insensible à la casse, on peut écrire une méthode personnalisée à l'intérieur de la Day
enum, par exemple
public static Day lookup(String day) {
for (Day d : Day.values()) {
if (d.name().equalsIgnoreCase(day)) {
return type;
}
}
return null;
}
Est-il de toute façon générique, sans utiliser la mise en cache de valeurs ou autres objets supplémentaires, à écrire une statique lookup()
méthode comme ci-dessus qu'une seule fois (c'est à dire, pas pour tous les enum
), étant donné que la values()
méthode est implicitement ajoutée à la Enum<E>
classe au moment de la compilation?
La signature d'un tel "générique" lookup()
méthode serait semblable à la Enum.valueOf()
méthode, c'est à dire:
public static <T extends Enum<T>> T lookup(Class<T> enumType, String name);
et qu'il mettrait en œuvre exactement la fonctionnalité de la Day.lookup()
méthode pour n'importe quel enum
, sans avoir besoin de ré-écrire la même méthode pour chaque enum
.
- Je suis sûr que vous le savez, mais la raison pourquoi le problème est apparu, c'est que vous ne respectez pas les enum de Java convention de nommage. Si vous avez été en utilisant la norme majuscules de nommage, vous utilisez simplement
Day.valueOf(day.toUpperCase())
dans votre méthode de recherche - Non, la même exigence s'applique quel que soit le cas ou d'autres conventions de nommage. Une méthode commune pour toutes les fins de la demande. 🙂
- L'ajout de @kiedysktos suggestion (ce qui, pour quelqu'un d'autre lecture, est de loin la solution la plus simple), je soupçonne OP cassé la convention d'affectation de noms parce qu'ils veulent le toString forme d'avoir uniquement la première lettre en majuscule comme c'est grammaticalement correct en anglais. Vous pouvez toujours accomplir ce en surchargeant la méthode toString:
return super.toString().substring(0, 1).toUpperCase() + super.toString().substring(1);
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé arriver le mélange spécial de génériques est un peu délicat, mais cela fonctionne.
Exemple
getEnumConstants()
méthode. J'étais en train d'essayer d'éviter d'appeler levalues()
méthode par réflexion, qui est ce que lagetEnumConstants()
en fait, mais apparemment, il n'y a pas de meilleure approche. Par ailleurs, vous pouvez simplement utiliserequalsIgnoreCase()
pour la comparaison de chaînes de caractères.Map<String, MyEnum>
où la valeur est déjà mis en minuscule ou quelque chose.Je pense que le plus simple moyen sûr de le faire serait:
Ou si vous souhaitez utiliser la classe de l'objet, puis:
values()
méthode n'est pas disponible pour leenumType
paramètre, qui est de typeClass<T>
.À partir de la version 3.8 apache commons-lang EnumUtils a deux pratique des méthodes pour cela:
getEnumIgnoreCase(final Class<E> enumClass, final String enumName)
isValidEnumIgnoreCase(final Class<E> enumClass, final String enumName)
Une solution générique serait de keeo à la convention qui constantes sont en majuscules. (Ou, dans votre cas, utilisez un capitaliser sur la chaîne).
Pour Android et relativement court, les Énumérations, je fais de la simple boucle et de comparer le nom d'ignorer le cas.
Vous pouvez utiliser
Class
dugetEnumConstants()
méthode, qui retourne un tableau de tous les types enum, si leClass
représente un enum, ounull
si ce n'.Optimisé pour la boucle de la ligne devrait ressembler à ceci:
Probablement, vous pouvez écrire une classe utilitaire pour faire comme les suivantes.
Il aurait été agréable si il y avait un moyen en Java pour la prolongation de la classe Enum par implicitement l'ajout de méthodes juste la façon dont les valeurs de() la méthode est ajouté, mais je ne pense pas qu'il existe un moyen de le faire.
Je suis à l'aide de cette façon comparaison insensible à la casse d'une chaîne à une enum de java
Day[] days = Day.values();
for(Day day: days) {
System.out.println("MONDAY".equalsIgnoreCase(day.name()));
}