Ich möchte eine Aufzählung anhand ihres Zeichenfolgenwerts (oder möglicherweise eines anderen Werts) nachschlagen. Ich habe den folgenden Code ausprobiert, aber er erlaubt keine statische Aufladung in Initialisierern. Gibt es einen einfachen Weg?
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
Initialisierung führen). Die übliche Lösung besteht darin, eine verschachtelte Klasse zu verwenden.Antworten:
Verwenden Sie die
valueOf
Methode, die automatisch für jede Aufzählung erstellt wird.Für beliebige Werte beginnen Sie mit:
Fahren Sie erst später mit der Map-Implementierung fort, wenn Sie von Ihrem Profiler dazu aufgefordert werden.
Ich weiß, dass es über alle Werte iteriert, aber mit nur 3 Aufzählungswerten ist es kaum eine andere Anstrengung wert. Wenn Sie nicht viele Werte haben, würde ich mich nicht um eine Karte kümmern, wird es schnell genug sein.
quelle
IllegalArgumentException
Null auslösen, anstatt eine Null zurückzugeben ( dh wenn keine Übereinstimmung gefunden wird). SoEnum.valueOf(..)
macht es das JDK jedenfalls.Du bist nah dran. Versuchen Sie für beliebige Werte Folgendes:
quelle
HashMap<>
zum Speichern der Aufzählungen verwendet über 40% schneller als eine Bodenschleife.Mit Java 8 können Sie Folgendes erreichen:
quelle
null
. Aber es hängt auch vom Anwendungsfall ab@ Lyles Antwort ist ziemlich gefährlich und ich habe gesehen, dass es nicht besonders funktioniert, wenn Sie die Aufzählung zu einer statischen inneren Klasse machen. Stattdessen habe ich so etwas verwendet, das die BootstrapSingleton-Maps vor den Aufzählungen lädt.
Bearbeiten Dies sollte mit modernen JVMs (JVM 1.6 oder höher) kein Problem mehr sein, aber ich denke, es gibt immer noch Probleme mit JRebel, aber ich hatte keine Chance, es erneut zu testen .
Lade mich zuerst:
Laden Sie es nun in den Enum-Konstruktor:
Wenn Sie eine innere Aufzählung haben, können Sie einfach die Karte über der Aufzählungsdefinition definieren und diese sollte (theoretisch) vorher geladen werden.
quelle
Und Sie können valueOf () nicht verwenden ?
Bearbeiten: Übrigens hindert Sie nichts daran, statisches {} in einer Aufzählung zu verwenden.
quelle
valueOf
Aufzählungsklasse, sodass Sie die Aufzählungsklasse nicht angeben müssenClass
.Falls es anderen hilft, verwendet die von mir bevorzugte Option, die hier nicht aufgeführt ist, die Kartenfunktion von Guava :
Mit der Standardeinstellung, die Sie verwenden können
null
, könnenthrow IllegalArgumentException
oder können SiefromString
einOptional
beliebiges Verhalten zurückgeben.quelle
Seit Java 8 können Sie die Karte in einer einzigen Zeile und ohne statischen Block initialisieren
quelle
Function.identity()
, ich finde sie textlich viel ansprechender alse -> e
.Vielleicht werfen Sie einen Blick darauf. Es funktioniert für mich. Der Zweck ist, 'RED' mit '/ red_color' nachzuschlagen. Das Deklarieren von a
static map
und dasenum
einmalige Laden des s würde einige Leistungsvorteile bringen, wennenum
es viele s gibt.Bitte geben Sie Ihre Meinung ein.
quelle
Sie können Ihre Aufzählung wie folgt definieren:
Weitere Informationen finden Sie unter folgendem Link
quelle
Wenn Sie einen Standardwert möchten und keine Lookup-Maps erstellen möchten, können Sie eine statische Methode erstellen, um dies zu handhaben. In diesem Beispiel werden auch Suchvorgänge behandelt, bei denen der erwartete Name mit einer Zahl beginnen würde.
Wenn Sie es für einen sekundären Wert benötigen, erstellen Sie zuerst die Lookup-Map wie in einigen anderen Antworten.
quelle
}}
quelle
Sie können die
Enum::valueOf()
von Gareth Davis & Brad Mace oben vorgeschlagene Funktion verwenden, aber stellen Sie sicher, dass Sie mit der Funktion umgehenIllegalArgumentException
, die ausgelöst wird, wenn die verwendete Zeichenfolge nicht in der Aufzählung vorhanden ist.quelle