Powiedz, że mam wyliczenie, które jest sprawiedliwe
public enum Blah {
A, B, C, D
}
i chciałbym znaleźć wartość wyliczenia łańcucha, na przykład, "A"
która byłaby Blah.A
. Jak byłoby to możliwe?
Czy Enum.valueOf()
potrzebuję metody? Jeśli tak, jak miałbym to wykorzystać?
Blah.valueOf("A")
metodzie rozróżniana jest wielkość liter i nie toleruje obcych białych znaków, dlatego alternatywne rozwiązanie zaproponowane poniżej przez @ JoséMi.toString()
wartość, nie, nie powiedziałbym tego.name()
dostanie ci faktycznie zdefiniowaną nazwę stałej wyliczeniowej, chyba że ją zastąpisz.enum Blah {...}
definicja nie powinna próbować deklarować własnejvalues
anivaluesOf
. To tak, jak możesz napisać „AnyTypeName.class”, nawet jeśli tak naprawdę nigdy nie zadeklarowałeś zmiennej „class”; kompilator sprawia, że wszystko działa. (Ta odpowiedź może nie być już przydatna 3 miesiące później, ale na wszelki wypadek.)Inne rozwiązanie, jeśli tekst nie jest taki sam jak wartość wyliczenia:
źródło
throw new IllegalArgumentException("No constant with text " + text + " found")
byłoby lepiej niżreturn null
.Oto fajne narzędzie, którego używam:
Następnie w mojej klasie enum zwykle mam to, aby zaoszczędzić trochę pisania:
Jeśli twoje wyliczenia nie są wszystkimi ograniczeniami, po prostu zmień
Enum.valueOf
linię.Szkoda, że nie można używać
T.class
naEnum.valueOf
coT
zostaną skasowane.źródło
Użyj wzoru z Joshua Bloch, Effective Java :
(uproszczony dla zwięzłości)
Zobacz także:
Przykład Oracle Java z wykorzystaniem Enum i mapy instancji
Kolejność wykonywania bloków statycznych w typie Enum
Jak mogę wyszukać wyliczenie Java na podstawie jego wartości String
źródło
Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))
Polecam również zastąpienie metody toString () (przekazanej przez konstruktor) i użycie jej zamiast nazwy, szczególnie jeśli Enum jest powiązany z szeregowalnymi danymi, ponieważ pozwala to kontrolować obudowę bez podawania Sonar pasuje.unmodifiableMap
, nie ma żadnej korzyści, aby zacząć odConcurrentHashMap
. Po prostu użyjHashMap
. (Jeśli maszImmutableMap
ConcurrentHashMap
tutaj, gdzie mapa nigdy nie jest modyfikowana po inicjalizacji. Dlatego nawet np. Przykład w samym JLS używa regularnegoHashMap
.Powinieneś także uważać na swoją sprawę. Pozwól, że wyjaśnię: robienie
Blah.valueOf("A")
prac, aleBlah.valueOf("a")
nie zadziała. Potem znowuBlah.valueOf("a".toUpperCase(Locale.ENGLISH))
by działało.edytuj
Zmieniono
toUpperCase
natoUpperCase(Locale.ENGLISH)
oparte na tc. komentarz i dokumenty javaedit2 Na Androidzie powinieneś używać
Locale.US
, jak wskazuje sulai .źródło
Locale.US
wejścia / wyjścia do odczytu maszynowego.Oto metoda, która może to zrobić dla dowolnego Enum i nie uwzględnia wielkości liter.
źródło
equalsIgnoreCase
jest to najlepsza droga. +1Używanie
Blah.valueOf(string)
jest najlepsze, ale możesz także korzystaćEnum.valueOf(Blah.class, string)
.źródło
W Javie 8 lub nowszej przy użyciu strumieni :
źródło
Jeśli nie chcesz pisać własnego narzędzia, skorzystaj z usług Google guawa biblioteka:
W przeciwieństwie do wbudowanej funkcji java pozwala sprawdzić, czy A jest obecny w Blah i nie zgłasza wyjątku.
źródło
Moje 2 centy tutaj: za pomocą strumieni Java8 + sprawdzenie dokładnego ciągu:
** EDYTOWAĆ **
Zmieniłem nazwę tej funkcji,
fromString()
ponieważ od jej nazwania przy użyciu tej konwencji uzyskasz pewne korzyści z samego języka Java; na przykład:źródło
switch
bloków, możesz.orElse(null)
zamiast.orElseThrow()
tego, aby kodować wyjątek wrzucającdefault
klauzulę - i zawierać bardziej przydatne informacje, gdy jest to wymagane. Aby uczynić go bardziej łagodnym, możesz użyćv -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
Optional
zfindFirst()
, pozwalając użytkownikowi zdecydować, czy chce.orElse(null)
,orElseThrow()
czy cokolwiek innego ...public static MyEnum valueOf(String)
jest w rzeczywistości błędem kompilacji, ponieważ jest taki sam jak domyślnie zdefiniowany, więc starsza wersja Twojej odpowiedzi jest w rzeczywistości lepsza. ( jls , ideone )Może być konieczne:
Jeszcze jeden dodatek:
Spowoduje to zwrócenie Ci wartości przez Strunową Nazwę Enum. Na przykład, jeśli podasz „PERSON” w fromEnumName, zwróci Ci wartość Enum, tj. „Osoba”
źródło
Innym sposobem osiągnięcia tego celu jest użycie niejawnej metody statycznej
name()
Enum. nazwa zwróci dokładny ciąg użyty do utworzenia tego wyliczenia, którego można użyć do sprawdzenia podanego ciągu:Testowanie:
System.out.println(Blah.getEnum("B").name());
inspiracja: 10 przykładów Enum w Javie
źródło
valueOf
robi dla ciebie. Ta statyczna metoda nie oferuje nic więcej, wyjątków i wszystkich innych. Zatem konstrukcje if / else są wysoce niebezpieczne ... każda nowa dodana stała wyliczania spowoduje, że ta metoda zepsuje się bez zmian.name()
nie jest statyczny.Rozwiązanie wykorzystujące biblioteki Guava. Metoda getPlanet () nie uwzględnia wielkości liter, więc getPlanet („MerCUrY”) zwróci Planet.MERCURY.
źródło
Aby dodać do poprzednich odpowiedzi i zająć się niektórymi dyskusjami wokół wartości zerowych i NPE, korzystam z Opcji Guava do obsługi nieobecnych / nieprawidłowych przypadków. Działa to doskonale w przypadku analizowania identyfikatora URI / parametru.
Dla tych, którzy nie są świadomi, oto kilka informacji na temat unikania wartości null za pomocą Opcjonalnego: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional
źródło
W Javie 8 statyczny wzorzec mapy jest jeszcze łatwiejszy i jest moją preferowaną metodą. Jeśli chcesz używać Enum z Jacksonem, możesz zastąpić toString i użyć tego zamiast nazwy, a następnie dokonać adnotacji za pomocą
@JsonValue
źródło
źródło
Metoda O (1) zainspirowana kodem generowanym przez oszczędność, który wykorzystuje hashap.
źródło
Enum jest bardzo przydatne, często
Enum
używałem do dodawania opisu dla niektórych pól w różnych językach, jak w poniższym przykładzie:Następnie możesz dynamicznie pobrać opis w oparciu o kod języka przekazany do
getDescription(String lang)
metody, na przykład:źródło
Co powiesz na?
źródło
java.lang.Enum
definiuje kilka użytecznych metod, które są dostępne dla wszystkich typów wyliczeń w Javie:name()
metody, aby uzyskać nazwę dowolnej stałej Enum. Dosłowne ciągi używane do pisania stałych enum to ich nazwy.values()
można użyć metody, aby uzyskać tablicę wszystkich stałych Enum z typu Enum.valueOf()
metody konwersji dowolnej wartości ciągu na stałą Enum w Javie, jak pokazano poniżej.W tym fragmencie kodu
valueOf()
metoda zwraca stałą Enum Gender.MALE, wywołującą nazwę na tej zwracanej wartości"MALE"
.źródło
Biblioteka commons-lang w Apache ma statyczną funkcję org.apache.commons.lang3.EnumUtils.getEnum, która zamapuje łańcuch na typ Enum. Ta sama odpowiedź w zasadzie jak Geoffreys, ale po co rzucać własną, skoro już jest na wolności.
źródło
Dodanie do najwyżej ocenianej odpowiedzi z przydatnym narzędziem ...
valueOf()
zgłasza dwa różne wyjątki w przypadkach, gdy nie podoba mu się jego wejście.IllegalArgumentException
NullPointerExeption
Jeśli twoje wymagania są takie, że nie masz żadnej gwarancji, że Twój ciąg z pewnością będzie pasował do wartości wyliczeniowej, na przykład jeśli dane ciągu pochodzą z bazy danych i mogą zawierać starą wersję wyliczenia, musisz je obsłużyć często...
Oto więc napisana przeze mnie metoda wielokrotnego użytku, która pozwala nam zdefiniować domyślny Enum, który zostanie zwrócony, jeśli przekazany przez nas Ciąg nie będzie pasował.
Użyj tego w ten sposób:
źródło
Ponieważ
switch
jeszcze nie wspomniano o -wersji, przedstawiam ją (ponownie wykorzystując wyliczenie OP):Ponieważ nie daje to żadnej dodatkowej wartości
valueOf(String name)
metodzie, sensowne jest zdefiniowanie dodatkowej metody, jeśli chcemy mieć inne zachowanie. Jeśli nie chcemy podnosićIllegalArgumentException
, możemy zmienić implementację na:Poprzez dostarczanie wartości domyślnej możemy utrzymać umowę o
Enum.valueOf(String name)
bez rzucającIllegalArgumentException
w ten sposób, że w żadnym wypadku nienull
jest zwracana. Dlatego rzucamy aNullPointerException
jeśli nazwa jest,null
adefault
jeślidefaultValue
jestnull
. Tak tovalueOfOrDefault
działa.W tym podejściu przyjęto projekt
Map
interfejsu, który zapewnia metodęMap.getOrDefault(Object key, V defaultValue)
od Java 8.źródło
Kolejne narzędzie przechwytujące w odwrotny sposób. Używanie wartości identyfikującej to Enum, a nie jego nazwa.
Przykład:
EnumUtil.from(Foo.class, "drei")
zwracaFoo.THREE
, ponieważ użyjegetValue
do dopasowania „drei”, która jest unikalną publiczną, a nie ostateczną i niestatyczną metodą w Foo. W przypadku Foo ma więcej niż o sposobie publicznego, a nie ostatecznego, a nie statycznym, na przykład,getTranslate
który powraca „drei”, druga metoda może być stosowana:EnumUtil.from(Foo.class, "drei", "getTranslate")
.źródło
Rozwiązanie Kotlin
Utwórz numer wewnętrzny, a następnie zadzwoń
valueOf<MyEnum>("value")
. Jeśli typ jest nieprawidłowy, otrzymasz null i będziesz musiał go obsłużyćAlternatywnie możesz ustawić wartość domyślną, wywołując
valueOf<MyEnum>("value", MyEnum.FALLBACK)
i unikając odpowiedzi zerowej. Możesz rozszerzyć swoje wyliczenie, aby domyślnie było automatyczneLub jeśli chcesz jedno i drugie, zrób drugie:
źródło
Lubię używać tego rodzaju procesu do analizowania poleceń jako ciągów znaków w wyliczeniach. Zwykle mam jedno z wyliczeń jako „nieznane”, więc warto zwrócić je, gdy nie zostaną znalezione inne (nawet bez rozróżniania wielkości liter), a nie puste (to znaczy, że nie ma wartości). Dlatego używam tego podejścia.
źródło
Najszybszym sposobem na uzyskanie nazwy wyliczenia jest utworzenie mapy tekstu i wartości wyliczenia podczas uruchamiania aplikacji oraz uzyskanie nazwy wywołanie funkcji Blah.getEnumName ():
źródło