Wie kann ich eine Java-Enumeration anhand ihres String-Werts suchen?

Ich würde gerne eine Aufzählung von seinem String-Wert (oder möglicherweise einem anderen Wert) suchen. Ich habe den folgenden Code ausprobiert, aber es erlaubt keine Initialisierer. Gibt es einen einfachen Weg?

public enum Verbosity { BRIEF, NORMAL, FULL; private static Map stringMap = new HashMap(); private Verbosity() { stringMap.put(this.toString(), this); } public static Verbosity getVerbosity(String key) { return stringMap.get(key); } }; 

    Verwenden Sie die Methode valueOf , die automatisch für jede Enum erstellt wird.

     Verbosity.valueOf("BRIEF") == Verbosity.BRIEF 

    Für beliebige Werte beginnen mit:

     public static Verbosity findByAbbr(String abbr){ for(Verbosity v : values()){ if( v.abbr().equals(abbr)){ return v; } } return null; } 

    Bewegen Sie sich erst später zur Map-Implementierung, wenn Ihr Profiler Ihnen dies sagt.

    Ich weiß, dass es über alle Werte iteriert, aber mit nur 3 Enum-Werten ist es kaum eine andere Anstrengung wert. Wenn man nicht viele Werte hat, würde ich mich nicht mit einer Karte beschäftigen, es wäre schnell genug.

    Du bist nah dran. Versuchen Sie etwas wie folgt:

     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 lookup = new HashMap(); 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); } } 

    @Lyles Antwort ist ziemlich gefährlich und ich habe gesehen, dass es nicht funktioniert, besonders wenn du das Enum zu einer statischen inneren class machst. Stattdessen habe ich etwas verwendet, das die BootstrapSingleton-Maps vor den Enums lädt.

    Bearbeiten Sie dies sollte kein Problem mehr mit modernen JVMs (JVM 1.6 oder höher) sein, aber ich denke, es gibt immer noch Probleme mit JRebel, aber ich hatte keine Chance, es erneut zu testen .

    Lade mich zuerst:

      public final class BootstrapSingleton { // Reverse-lookup map for getting a day from an abbreviation public static final Map lookup = new HashMap(); } 

    Laden Sie es nun im Enum-Konstruktor:

      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); } } 

    Wenn Sie eine innere Enumeration haben, können Sie einfach die Map oberhalb der Enum-Definition definieren und diese (theoretisch) sollte vorher geladen werden.

    Mit Java 8 können Sie auf diese Weise erreichen:

     public static Verbosity findByAbbr(final String abbr){ return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null); } 

    Und du kannst valueOf () nicht verwenden?

    Edit: Übrigens, es gibt nichts, was Sie davon abhält, statische {} in einem Enum zu verwenden.

    In der Java Language Specification 7 gibt es ein Beispiel ! das spiegelt Ihre Frage zur Initialisierung der Karte mit Selbstreferenzen wider.

    Falls es anderen hilft, verwendet die Option, die ich bevorzuge, die hier nicht aufgeführt ist, die Google Maps-functionalität :

     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 reverseLookup = Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue); public static Verbosity fromString(final String id) { return reverseLookup.getOrDefault(id, NORMAL); } } 

    Mit dem Standardwert können Sie null , Sie können throw IllegalArgumentException oder Ihr fromString kann ein Optional , welches Verhalten Sie auch bevorzugen.

    Vielleicht, sieh dir das an. Es funktioniert für mich. Der Zweck ist, ‘ROT’ mit ‘/ red_color’ nachzuschlagen. Das Deklarieren einer static map und das einmalige Laden der enum würde nur dann einige performancesvorteile bringen, wenn die enum viele sind.

     public class Mapper { public enum Maps { COLOR_RED("/red_color", "RED"); private final String code; private final String description; private static Map 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(); for (Maps s : Maps.values()) { mMap.put(s.code, s.description); } } } } 

    Bitte geben Sie Ihre Meinung ein.

    Sie können Ihre Enum als folgenden Code definieren:

     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(); } }; 

    Siehe folgenden Link für weitere Erläuterungen

    Sie können die function Enum::valueOf() wie oben von Gareth Davis & Brad Mace vorgeschlagen verwenden, aber stellen Sie sicher, dass Sie die IllegalArgumentException behandeln, die IllegalArgumentException würde, wenn die verwendete Zeichenfolge nicht in der IllegalArgumentException wäre.