Je voudrais rechercher une énumération de sa valeur de chaîne (ou éventuellement de toute autre valeur). J'ai essayé le code suivant mais il n'autorise pas les initialiseurs statiques. 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);
}
};
Utilisez la méthode valueOf
qui est créée automatiquement pour chaque énumération.
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
Pour les valeurs arbitraires, commencez par:
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
Ne passez à la mise en œuvre de la carte que si votre profileur vous le demande.
Je sais que c'est une itération de toutes les valeurs, mais avec seulement 3 valeurs d'énum, cela ne vaut pas la peine de faire un autre effort. En fait, à moins que vous ayez beaucoup de valeurs, je ne m'embêterais pas avec une carte, elle sera assez rapide.
Tu es proche. Pour des valeurs arbitraires, essayez l'une des solutions suivantes:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
// Reverse-lookup map for getting a day from an abbreviation
private static final Map<String, Day> lookup = new HashMap<String, Day>();
static {
for (Day d : Day.values()) {
lookup.put(d.getAbbreviation(), d);
}
}
private Day(String abbreviation) {
this.abbreviation = abbreviation;
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
avec Java 8, vous pouvez obtenir de cette manière:
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
La réponse de @ Lyle est plutôt dangereuse et je l'ai déjà vu ne pas fonctionner, surtout si vous faites de l'énum une classe interne statique. Au lieu de cela, j'ai utilisé quelque chose comme ceci qui chargera les cartes BootstrapSingleton avant les enums.
Edit cela ne devrait plus être un problème avec les JVM modernes (JVM 1.6 ou supérieure) mais je pense qu'il y a toujours des problèmes avec JRebel mais je n'ai pas eu une chance de le retester .
Charge moi d'abord:
public final class BootstrapSingleton {
// Reverse-lookup map for getting a day from an abbreviation
public static final Map<String, Day> lookup = new HashMap<String, Day>();
}
Maintenant, chargez-le dans le constructeur enum:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
private Day(String abbreviation) {
this.abbreviation = abbreviation;
BootstrapSingleton.lookup.put(abbreviation, this);
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
Si vous avez un enum interne, vous pouvez simplement définir la carte au-dessus de la définition de l’énum et cela (en théorie) devrait être chargé avant.
Et vous ne pouvez pas utiliser valueOf () ?
Edit: Btw, rien ne vous empêche d’utiliser static {} dans un enum.
Si cela peut aider les autres, l’option que je préfère, qui ne figure pas ici, utilise fonctionnalité de Guava's Maps :
public enum Vebosity {
BRIEF("BRIEF"),
NORMAL("NORMAL"),
FULL("FULL");
private String value;
private Verbosity(final String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
private static ImmutableMap<String, Verbosity> reverseLookup =
Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue);
public static Verbosity fromString(final String id) {
return reverseLookup.getOrDefault(id, NORMAL);
}
}
Par défaut, vous pouvez utiliser null
, vous pouvez throw IllegalArgumentException
ou votre fromString
peut renvoyer un Optional
, quel que soit le comportement que vous préférez.
Dans la Java Spécification du langage 7, il existe un n exemple ! cela reflète votre question sur l’initialisation de la carte avec des auto-références.
Peut-être, jetez un oeil à cela. Cela fonctionne pour moi. Le but de ceci est de rechercher 'RED' avec '/ red_color'. Déclarer un static map
et charger le enum
s une seule fois apporterait des avantages en termes de performances si les enum
s sont nombreux.
public class Mapper {
public enum Maps {
COLOR_RED("/red_color", "RED");
private final String code;
private final String description;
private static Map<String, String> mMap;
private Maps(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return name();
}
public String getDescription() {
return description;
}
public String getName() {
return name();
}
public static String getColorName(String uri) {
if (mMap == null) {
initializeMapping();
}
if (mMap.containsKey(uri)) {
return mMap.get(uri);
}
return null;
}
private static void initializeMapping() {
mMap = new HashMap<String, String>();
for (Maps s : Maps.values()) {
mMap.put(s.code, s.description);
}
}
}
}
S'il vous plaît mettez dans vos opinions.
Vous pouvez définir votre énumération comme code suivant:
public enum Verbosity
{
BRIEF, NORMAL, FULL, ACTION_NOT_VALID;
private int value;
public int getValue()
{
return this.value;
}
public static final Verbosity getVerbosityByValue(int value)
{
for(Verbosity verbosity : Verbosity.values())
{
if(verbosity.getValue() == value)
return verbosity ;
}
return ACTION_NOT_VALID;
}
@Override
public String toString()
{
return ((Integer)this.getValue()).toString();
}
};
depuis Java 8, vous pouvez initialiser la carte en une seule ligne et sans bloc statique
private static Map<String, Verbosity> stringMap = Arrays.stream(values())
.collect(Collectors.toMap(Enum::toString, Function.identity()));