Dzisiaj porozmawiamy o pracy z wyliczeniami łańcuchowymi, a dokładniej z
enum
klasami organizującymi interakcję ze stałymi łańcuchowymi.
Korzystanie z wyliczeń ciągów
Podczas tworzenia aplikacji należy okresowo operować na ustalonym zestawie wartości łańcuchowych. To może być cokolwiek. Przykładowo lista kodów kolorów obsługiwanych przez aplikację, czy lista urządzeń z którymi nasza aplikacja może współpracować, pory roku itp. Wszystko to jest predefiniowanym zestawem stałych stringowych o wspólnej strukturze, z którymi konieczne jest ustalenie interakcji programu na poziomie kodu Java. Kiedy zachodzi potrzeba interakcji z predefiniowanym zestawem stałych łańcuchowych (i innych), najlepszym rozwiązaniem jest napisanie własnejenum
klasy. Poniżej przyjrzymy się przykładom konwersji enum
do formatu string
.
Tworzenie wyliczeń ciągów
Stwórzmyenum
klasę przechowującą listę różnych środowisk do wdrażania aplikacji, a także adres URL każdego środowiska:
public enum Environment {
PROD("https://release.application.com/"),
TEST("https://test.application.com/"),
AUTO_TEST("https://autotest.application.com/"),
DEV("http://localhost:8080");
private final String url;
Environment(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
}
W tej klasie zdefiniowaliśmy 4 środowiska:
PROD
- uwolnienieTEST
— do testów ręcznychAUTO_TEST
— środowisko do autotestówDEV
— lokalny do programowania i debugowania
- W naszym wyliczeniu każdy adres URL jest stałą łańcuchową: są one zdefiniowane w nawiasach obok każdej
enum
stałej. - Musi istnieć konstruktor, który przyjmuje argument tego samego typu co każda
enum
stała. - Zakres konstruktora
private
topackage private
. - Konieczne jest zdefiniowanie zmiennej - pola klasy, w którym będą przechowywane zdefiniowane przez nas stałe łańcuchowe. Aby móc używać wartości stałych stringowych na zewnątrz, należy utworzyć metodę gettera dla tego pola.
Iterowanie po wyliczeniach ciągów
Na tym etapie możemy już iterować po wszystkich dostępnychenum
wartościach, a także uzyskać powiązane z nimi stałe łańcuchowe. Aby uzyskać wszystkie wartości dowolnej enum
klasy, musisz użyć metody values()
:
public class Main {
public static void main(String[] args) {
for (Environment env : Environment.values()) {
System.out.println(env + " : " + env.getUrl());
}
}
}
Wniosek:
PROD : https://release.application.com/
TEST : https://test.application.com/
AUTO_TEST : https://autotest.application.com/
DEV : http://localhost:8080
Jak widać na przykładzie, aby wydrukować nazwę enum
stałej, przekazaliśmy ją do metody System.out.println
, a do wydrukowania adresu URL powiązanego z tą stałą, wykorzystaliśmy zdefiniowany przez nas getter.
Pobieranie stałej łańcuchowej z wyliczenia
Aby uzyskać wartość dowolnej stałej łańcuchowej, możemy również wywołać funkcję pobierającą na dowolnejenum
stałej:
public class Main {
public static void main(String[] args) {
String prodUrl = Environment.PROD.getUrl();
String devUrl = Environment.DEV.getUrl();
System.out.println("Production url is: " + prodUrl);
System.out.println("Development url is: " + devUrl);
}
}
Wniosek:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
Uzyskiwanie stałej wyliczeniowej według nazwy
Czasami konieczne jest uzyskanieenum
stałej według jej nazwy ciągu. Odbywa się to za pomocą metody valueOf(String)
, która zwraca stałą według jej nazwy:
public class Main {
public static void main(String[] args) {
Environment prod = Environment.valueOf("PROD");
Environment dev = Environment.valueOf("DEV");
System.out.println("Production url is: " + prod.getUrl());
System.out.println("Development url is: " + dev.getUrl());
}
}
Wniosek:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
Ale tutaj konieczna jest ostrożność. Jeśli metoda nie znajdzie enum
stałej o podanej nazwie, zostanie zgłoszony wyjątek java.lang.IllegalArgumentException
.
Konwersja ciągu na wyliczenie
Czasami pojawia się potrzeba odwrotna. Znając wartośćenum
, uzyskaj enum
samą stałą. Te. w naszym przykładzie, znając określony adres, musisz uzyskać odpowiednią Environment
stałą. Można to zrobić na kilka sposobów. I wszystkie wymagają poprawy w enum
samej klasie. Opcja 1. Wyliczenie wewnątrz klasy. Musisz stworzyć metodę, która zaakceptuje ciąg znaków i porówna go ze wszystkimi wartościami enum
klasy. Jeśli istnieje dopasowanie, metoda zwróci żądane wyliczenie. W naszym przykładzie musimy Environment
utworzyć w klasie następującą metodę:
public static Environment getEnvByUrl(String url) {
for (Environment env : values()) {
// либо equalsIgnoreCase, на ваше усмотрение
if (env.getUrl().equals(url)) {
return env;
}
}
// Либо просто вернуть null
throw new IllegalArgumentException("No enum found with url: [" + url + "]");
}
Następnie możemy uzyskać enum
z ciągu znaków w następujący sposób:
public class Main {
public static void main(String[] args) {
String url = "http://localhost:8080";
Environment env = Environment.getEnvByUrl(url);
System.out.println("Environment name for url=[" + url + "] is: " + env);
}
}
Wniosek:
Environment name for url=[http://localhost:8080] is: DEV
To podejście ma swoje wady. Za każdym razem, aby uzyskać enum
stałą, będziesz musiał iterować po wszystkich wartościach i dokonywać określonej liczby porównań. W tym przypadku spadek wydajności zostanie określony na podstawie liczby stałych i liczby podobnych operacji. Druga metoda rozwiązania tego problemu nie ma tego problemu. Pełny Enum
kod klasy:
public enum Environment {
PROD("https://release.application.com/"),
TEST("https://test.application.com/"),
AUTO_TEST("https://autotest.application.com/"),
DEV("http://localhost:8080");
private final String url;
Environment(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public static Environment getEnvByUrl(String url) {
for (Environment env : values()) {
if (env.getUrl().equals(url)) {
return env;
}
}
throw new IllegalArgumentException("No enum found with url: [" + url + "]");
}
}
Opcja 2: Użycie HashMap
W tym przypadku tworzymy mapę wewnątrz naszego wyliczenia i wypełniamy ją raz w czasie kompilacji, a następnie pobieramy z niej wartości:
public enum Environment {
PROD("https://release.application.com/"),
TEST("https://test.application.com/"),
AUTO_TEST("https://autotest.application.com/"),
DEV("http://localhost:8080");
private final String url;
Environment(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
// Создаем static final карту
private static final Map<String, Environment> LOOKUP_MAP = new HashMap<>();
// Заполняем её всеми значениями
static {
for (Environment env : values()) {
LOOKUP_MAP.put(env.getUrl(), env);
}
}
// Возвращаем Environment по строковому url
public static Environment getEnvByUrl(String url) {
return LOOKUP_MAP.get(url);
}
}
Pod względem użytkowania obie opcje są identyczne:
public class Main {
public static void main(String[] args) {
String url = "http://localhost:8080";
Environment env = Environment.getEnvByUrl(url);
System.out.println("Environment name for url=[" + url + "] is: " + env);
}
}
Wniosek:
Environment name for url=[http://localhost:8080] is: DEV
Ale ta metoda ma również wady. Po pierwsze, jest znacznie więcej kodu. Po drugie, HashMap
wszystkie enum
wartości zostaną zapisane w pamięci aplikacji na stałe. Jak widać wszystko ma wady i zalety. Biorąc jednak pod uwagę, że enum
klasy zwykle przechowują niewiele wartości, wady będą prawie niezauważalne. Jest zastrzeżenie: jeśli taka operacja (pobieranie wartości Java Enum przez ciąg znaków) jest wykonywana często, lepiej skorzystać z drugiej opcji. Więcej na ten temat i Enum
zajęcia w ogóle możesz dowiedzieć się z kursu JavaRush. Studenci uczą się języka JavaRush Enum
już na pierwszym wykładzie piątego poziomu .
GO TO FULL VERSION