Chciałbym wyszukać wyliczenie na podstawie jego wartości ciągu (lub ewentualnie dowolnej innej wartości). Wypróbowałem następujący kod, ale nie zezwala on na statyczne w inicjatorach. Czy istnieje prosty sposób?
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
inicjalizacji). Typowym rozwiązaniem jest użycie klasy zagnieżdżonej.Odpowiedzi:
Użyj
valueOf
metody, która jest tworzona automatycznie dla każdego Enum.Dla dowolnych wartości zacznij od:
Przejdź później do implementacji mapy tylko wtedy, gdy Twój profiler Ci to zaleci.
Wiem, że iteruje po wszystkich wartościach, ale przy tylko 3 wartościach wyliczeniowych nie jest to warte żadnego innego wysiłku, w rzeczywistości, jeśli nie masz wielu wartości, nie zawracałbym sobie głowy mapą, będzie wystarczająco szybko.
źródło
IllegalArgumentException
wartości null zamiast zwracania wartości null ( tj. Gdy nie zostanie znalezione żadne dopasowanie) -Enum.valueOf(..)
zresztą tak robi to JDK .Jesteś blisko. W przypadku dowolnych wartości spróbuj czegoś takiego:
źródło
HashMap<>
do przechowywania wyliczeń okazało się ponad 40% szybciej niż pętla podłogowa.z Javą 8 możesz osiągnąć w ten sposób:
źródło
null
. Ale zależy to również od przypadku użyciaOdpowiedź @ Lyle jest raczej niebezpieczna i widziałem, że nie działa, szczególnie jeśli uczynisz enum statyczną klasą wewnętrzną. Zamiast tego użyłem czegoś takiego, który załaduje mapy BootstrapSingleton przed wyliczeniami.
Edycja tego nie powinna już stanowić problemu w przypadku nowoczesnych maszyn JVM (JVM 1.6 lub nowszych), ale myślę, że nadal występują problemy z JRebel, ale nie miałem okazji go ponownie przetestować .
Załaduj mnie najpierw:
Teraz załaduj go do konstruktora wyliczenia:
Jeśli masz wewnętrzne wyliczenie, możesz po prostu zdefiniować Mapę powyżej definicji wyliczenia i to (teoretycznie) powinno zostać załadowane wcześniej.
źródło
I nie możesz użyć valueOf () ?
Edycja: przy okazji, nic nie stoi na przeszkodzie, abyś używał static {} w wyliczeniu.
źródło
valueOf
w klasie wyliczenia, więc nie musisz określać klasy wyliczeniaClass
.W przypadku, gdy pomaga to innym, preferowana przeze mnie opcja, której tutaj nie ma, wykorzystuje funkcjonalność map Guavy :
Z domyślnym ustawieniem, którego możesz użyć
null
, możeszthrow IllegalArgumentException
lub możeszfromString
zwrócićOptional
dowolne zachowanie.źródło
od wersji Java 8 możesz zainicjować mapę w jednej linii i bez statycznego bloku
źródło
Function.identity()
, uważam, że jest o wiele bardziej pociągający tekstowo niże -> e
.Może spójrz na to. To działa dla mnie. Celem tego jest wyszukanie „RED” za pomocą „/ red_color”. Zadeklarowanie a
static map
i załadowanie do niegoenum
s tylko raz przyniosłoby pewne korzyści w zakresie wydajności, jeślienum
jest ich wiele.Prosimy o wyrażenie opinii.
źródło
Możesz zdefiniować swój Enum jako następujący kod:
Zobacz poniższy link, aby uzyskać więcej wyjaśnień
źródło
Jeśli chcesz mieć wartość domyślną i nie chcesz tworzyć map wyszukiwania, możesz utworzyć statyczną metodę do obsługi tego. Ten przykład obsługuje również wyszukiwania, w których oczekiwana nazwa zaczynałaby się od liczby.
Jeśli potrzebujesz go na wartości drugorzędnej, najpierw zbuduj mapę wyszukiwania, tak jak w niektórych innych odpowiedziach.
źródło
}
źródło
Możesz użyć
Enum::valueOf()
funkcji zgodnie z sugestią Garetha Davisa i Brada Mace'a powyżej, ale upewnij się, że obsłużysz toIllegalArgumentException
, co zostanie wyrzucone, jeśli użyty ciąg nie jest obecny w wyliczeniu.źródło