Angenommen, ich habe eine Aufzählung, die gerecht ist
public enum Blah {
A, B, C, D
}
und ich möchte zum Beispiel den Aufzählungswert eines Strings finden, "A"
der wäre Blah.A
. Wie wäre das möglich?
Ist das Enum.valueOf()
die Methode, die ich brauche? Wenn ja, wie würde ich das verwenden?
Blah.valueOf("A")
Methode zwischen Groß- und Kleinschreibung und toleriert keine Leerzeichen, daher die unten von @ JoséMi vorgeschlagene alternative Lösung.toString()
Wert meinst , nein, das würde ich nicht sagen.name()
Sie erhalten den tatsächlich definierten Namen der Enum-Konstante, sofern Sie ihn nicht überschreiben.enum Blah {...}
Definition sollte nicht versuchen, ihre eigenevalues
noch zu deklarierenvaluesOf
. Es ist so, wie Sie "AnyTypeName.class" schreiben können, obwohl Sie nie eine "class" -Mitgliedsvariable deklariert haben. Der Compiler macht alles einfach. (Diese Antwort kann für Sie 3 Monate später nicht mehr nützlich sein, aber nur für den Fall.)Eine andere Lösung, wenn der Text nicht mit dem Aufzählungswert übereinstimmt:
quelle
throw new IllegalArgumentException("No constant with text " + text + " found")
wäre besser alsreturn null
.Hier ist ein nützliches Dienstprogramm, das ich verwende:
Dann habe ich in meiner Enum-Klasse normalerweise Folgendes, um etwas Tippen zu sparen:
Wenn Ihre Aufzählungen nicht alle Großbuchstaben sind, ändern Sie einfach die
Enum.valueOf
Zeile.Schade , kann ich nicht verwenden ,
T.class
fürEnum.valueOf
wieT
gelöscht wird.quelle
Verwenden Sie das Muster von Joshua Bloch, Effective Java :
(der Kürze halber vereinfacht)
Siehe auch:
Oracle Java-Beispiel mit Enum und Map of Instances
Ausführungsreihenfolge von statischen Blöcken in einem Enum-Typ
Wie kann ich eine Java-Enumeration anhand ihres String-Werts nachschlagen?
quelle
Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))
Ich empfehle außerdem, toString () (über den Konstruktor übergeben) zu überschreiben und diesen anstelle des Namens zu verwenden, insbesondere wenn die Aufzählung mit serialisierbaren Daten verknüpft ist, da Sie so das Gehäuse steuern können, ohne dies anzugeben Sonar ein Anfall.unmodifiableMap
trotzdem in ein setzen wollen, dann hat es keinen Vorteil, mit einem zu beginnenConcurrentHashMap
. Verwenden Sie einfach eineHashMap
. (Wenn SieImmutableMap
ConcurrentHashMap
, da die Karte nach der Initialisierung niemals geändert wird. Daher verwendet auch zB das Beispiel im JLS selbst eine reguläreHashMap
.Sie sollten auch mit Ihrem Fall vorsichtig sein. Lassen Sie mich erklären:
Blah.valueOf("A")
Arbeiten funktioniert, wird aberBlah.valueOf("a")
nicht funktionieren. DannBlah.valueOf("a".toUpperCase(Locale.ENGLISH))
würde wieder funktionieren.edit
Geändert
toUpperCase
zutoUpperCase(Locale.ENGLISH)
basierend auf tc. Kommentar und die Java-Dokumenteedit2 Auf Android solltest du verwenden
Locale.US
, wie Sulai betont .quelle
Locale.US
maschinenlesbaren Ein- / Ausgaben fördert .Hier ist eine Methode, die dies für jede Aufzählung tun kann und bei der die Groß- und Kleinschreibung nicht berücksichtigt wird.
quelle
equalsIgnoreCase
ist der richtige Weg. +1Verwenden
Blah.valueOf(string)
ist am besten, aber Sie können auch verwendenEnum.valueOf(Blah.class, string)
.quelle
In Java 8 oder höher mit Streams :
quelle
Wenn Sie kein eigenes Dienstprogramm schreiben möchten, verwenden Sie das von Google Guave Bibliothek:
Im Gegensatz zur integrierten Java-Funktion können Sie überprüfen, ob A in Blah vorhanden ist, und keine Ausnahme auslösen.
quelle
Meine 2 Cent hier: Verwenden von Java8 Streams + Überprüfen einer genauen Zeichenfolge:
** BEARBEITEN **
Wenn Sie die Funktion in umbenannt haben,
fromString()
da Sie sie mit dieser Konvention benannt haben, profitieren Sie von der Java-Sprache selbst. zum Beispiel:quelle
switch
Blöcke schreiben können,.orElse(null)
stattdessen.orElseThrow()
den Ausnahmefall in derdefault
Klausel codieren und bei Bedarf weitere nützliche Informationen hinzufügen. Und um es milder zu machen, könnten Sie verwendenv -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
Optional
ausfindFirst()
, so dass der Benutzer entscheiden , ob er will.orElse(null)
,orElseThrow()
oder was auch immer ....public static MyEnum valueOf(String)
ist tatsächlich ein Kompilierungsfehler, da es mit dem implizit definierten identisch ist, sodass die ältere Version Ihrer Antwort tatsächlich besser ist. ( jls , ideone )Möglicherweise benötigen Sie dazu:
Noch eine Ergänzung:
Dies gibt Ihnen den Wert durch einen Stringified Enum-Namen zurück. Wenn Sie beispielsweise "PERSON" in fromEnumName angeben, erhalten Sie den Wert von Enum, dh "Person".
quelle
Eine andere Möglichkeit, dies zu tun, ist die implizite statische Methode
name()
von Enum. name gibt die genaue Zeichenfolge zurück, die zum Erstellen dieser Aufzählung verwendet wurde, mit der die angegebene Zeichenfolge überprüft werden kann:Testen:
System.out.println(Blah.getEnum("B").name());
Inspiration: 10 Beispiele für Enum in Java
quelle
valueOf
für Sie tut. Diese statische Methode bietet keine zusätzlichen Ausnahmen. Dann sind die if / else-Konstrukte sehr gefährlich ... jede neue hinzugefügte Enum-Konstante führt dazu, dass diese Methode ohne Änderung unterbrochen wird.name()
ist nicht statisch.Lösung mit Guava-Bibliotheken. Bei der Methode getPlanet () wird die Groß- und Kleinschreibung nicht berücksichtigt, daher gibt getPlanet ("MerCUrY") Planet.MERCURY zurück.
quelle
Um die vorherigen Antworten zu ergänzen und einige der Diskussionen um Nullen und NPE anzusprechen, verwende ich Guava-Optionen, um fehlende / ungültige Fälle zu behandeln. Dies funktioniert hervorragend für die URI- / Parameteranalyse.
Für diejenigen, die es nicht wissen, finden Sie hier weitere Informationen zum Vermeiden von Null mit Optional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional
quelle
In Java 8 ist das statische Kartenmuster noch einfacher und meine bevorzugte Methode. Wenn Sie die Aufzählung mit Jackson verwenden möchten, können Sie toString überschreiben und diese anstelle des Namens verwenden und dann mit kommentieren
@JsonValue
quelle
quelle
O (1) -Methode, inspiriert von sparsam erzeugtem Code, der eine Hashmap verwendet.
quelle
Enum ist sehr nützlich. Ich habe
Enum
viel verwendet, um eine Beschreibung für einige Felder in verschiedenen Sprachen hinzuzufügen, wie im folgenden Beispiel:Anschließend können Sie die Beschreibung dynamisch anhand des an die
getDescription(String lang)
Methode übergebenen Sprachcodes abrufen , z. B.:quelle
Wie wäre es mit?
quelle
java.lang.Enum
definiert mehrere nützliche Methoden, die für alle Aufzählungstypen in Java verfügbar sind:name()
Methode verwenden, um den Namen aller Enum-Konstanten abzurufen. String-Literal zum Schreiben von Enum-Konstanten ist ihr Name.values()
Weise kann die Methode verwendet werden, um ein Array aller Enum-Konstanten von einem Enum-Typ abzurufen.valueOf()
Methode verwenden, um einen beliebigen String in eine Enum-Konstante in Java zu konvertieren, wie unten gezeigt.In diesem
valueOf()
Codeausschnitt gibt die Methode eine Enum-Konstante Gender.MALE zurück, die den Namen aufruft, der zurückgegeben wird"MALE"
.quelle
Die commons-lang- Bibliothek von Apache verfügt über eine statische Funktion org.apache.commons.lang3.EnumUtils.getEnum, die Ihrem Enum-Typ einen String zuordnet . Dieselbe Antwort im Wesentlichen wie bei Geoffreys, aber warum sollten Sie Ihre eigenen rollen, wenn es schon in freier Wildbahn ist?
quelle
Hinzufügen zu der am besten bewerteten Antwort mit einem hilfreichen Dienstprogramm ...
valueOf()
löst zwei verschiedene Ausnahmen aus, wenn die Eingabe nicht gefällt.IllegalArgumentException
NullPointerExeption
Wenn Ihre Anforderungen so sind, dass Sie keine Garantie dafür haben, dass Ihr String definitiv mit einem Aufzählungswert übereinstimmt, z. B. wenn die String-Daten aus einer Datenbank stammen und eine alte Version der Aufzählung enthalten könnten, müssen Sie diese verarbeiten häufig...
Hier ist eine wiederverwendbare Methode, mit der wir eine Standard-Enum definieren können, die zurückgegeben werden soll, wenn der von uns übergebene String nicht übereinstimmt.
Verwenden Sie es so:
quelle
Da eine
switch
-Version noch nicht erwähnt wurde, stelle ich sie vor (Wiederverwendung der Aufzählung von OP):Da dies der
valueOf(String name)
Methode keinen zusätzlichen Wert verleiht , ist es nur dann sinnvoll, eine zusätzliche Methode zu definieren, wenn wir ein anderes Verhalten wünschen. Wenn wir keine erhöhen möchten,IllegalArgumentException
können wir die Implementierung ändern in:Durch die Angabe eines Standardwertes behalten wir den Vertrag bei,
Enum.valueOf(String name)
ohne einenIllegalArgumentException
auf diese Weise zu werfen , der in keinem Fallnull
zurückgegeben wird. Deshalb werfen wir einNullPointerException
if der Name istnull
und fallsdefault
ifdefaultValue
istnull
. SovalueOfOrDefault
funktioniert es.Dieser Ansatz übernimmt das Design der
Map
-Interface, die eine MethodeMap.getOrDefault(Object key, V defaultValue)
ab Java 8 bereitstellt .quelle
Ein weiteres Dienstprogramm, das in umgekehrter Weise erfasst. Verwenden eines Werts, der diese Aufzählung identifiziert, nicht anhand ihres Namens.
Beispiel:
EnumUtil.from(Foo.class, "drei")
Gibt zurückFoo.THREE
, da es verwendet wird,getValue
um mit "drei" übereinzustimmen, einer eindeutigen öffentlichen, nicht endgültigen und nicht statischen Methode in Foo. Wenn Foo beispielsweise mehr als eine öffentliche, keine endgültige und keine statische Methode hat,getTranslate
die "drei" zurückgibt, kann die andere Methode verwendet werden :EnumUtil.from(Foo.class, "drei", "getTranslate")
.quelle
Kotlin-Lösung
Erstellen Sie eine Nebenstelle und rufen Sie dann an
valueOf<MyEnum>("value")
. Wenn der Typ ungültig ist, erhalten Sie null und müssen damit umgehenAlternativ können Sie einen Standardwert festlegen, aufrufen
valueOf<MyEnum>("value", MyEnum.FALLBACK)
und eine Nullantwort vermeiden. Sie können Ihre spezifische Aufzählung so erweitern, dass die Standardeinstellung automatisch istOder wenn Sie beides wollen, machen Sie das zweite:
quelle
Ich verwende diese Art von Prozess gerne, um Befehle als Zeichenfolgen in Aufzählungen zu analysieren. Normalerweise habe ich eine der Aufzählungen als "unbekannt", daher ist es hilfreich, diese zurückzugeben, wenn die anderen nicht gefunden werden (auch wenn die Groß- und Kleinschreibung nicht berücksichtigt wird) und nicht null (dh es gibt keinen Wert). Daher verwende ich diesen Ansatz.
quelle
Der schnellste Weg, um den Namen von enum zu erhalten, besteht darin, beim Start der Anwendung eine Karte mit Aufzählungstext und -wert zu erstellen. Um den Namen zu erhalten, rufen Sie die Funktion Blah.getEnumName () auf:
quelle