今天我們將討論如何使用字串枚舉,更具體地說,如何
enum
使用組織與字串常數互動的類別。
使用字串枚舉
在應用程式開發過程中,您定期需要對一組固定的字串值進行操作。它可以是任何東西。例如,應用程式支援的顏色代碼列表,或我們的應用程式可以與之互動的裝置列表、季節等。所有這些都是一組預先定義的具有公共結構的字串常數,需要使用它們在 Java 程式碼層級建立程式互動。當您需要與一組預先定義的字串(和其他)常數互動時,最好的解決方案是編寫自己的enum
類別。下面我們將看一下轉換enum
為string
.
建立字串枚舉
讓我們建立enum
一個類別來儲存用於部署應用程式的不同環境的列表,以及每個環境的 URL:
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;
}
}
在這個類別中我們定義了4個環境:
PROD
- 發布TEST
— 用於手動測試AUTO_TEST
— 自動測試環境DEV
— 用於開發和調試的本機
- 在我們的枚舉中,每個 URL 都是字串常數:它們在每個常數旁邊的括號中定義
enum
。 - 必須有一個建構函數採用與每個常數相同類型的參數
enum
。 - 構造函數的範圍
private
是package private
. - 有必要定義一個變數 - 一個類別字段,它將儲存我們定義的字串常數。您必須為此欄位建立一個 getter 方法,以便在外部使用字串常數的值。
迭代字串枚舉
在此階段,我們已經可以迭代所有可用enum
值,並取得與它們關聯的字串常數。要取得任何類別的所有值enum
,需要使用以下方法values()
:
public class Main {
public static void main(String[] args) {
for (Environment env : Environment.values()) {
System.out.println(env + " : " + env.getUrl());
}
}
}
結論:
PROD : https://release.application.com/
TEST : https://test.application.com/
AUTO_TEST : https://autotest.application.com/
DEV : http://localhost:8080
從範例中可以看出,為了列印enum
常數的名稱,我們將其傳遞給方法System.out.println
,並使用我們定義的 getter 來列印與該常數關聯的 url。
從枚舉中取得字串常數
要取得任何字串常數的值,我們也可以對任何enum
常數呼叫 getter:
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);
}
}
結論:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
透過名稱取得枚舉常量
有時需要enum
透過字串名稱取得常數。這是使用 方法 完成的valueOf(String)
,該方法按名稱傳回一個常數:
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());
}
}
結論:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
但這裡需要謹慎。如果該方法沒有找到enum
具有指定名稱的常數,則會拋出異常java.lang.IllegalArgumentException
。
將字串轉換為枚舉
有時會出現相反的需求。知道值enum
,就可以得到enum
常數本身。那些。在我們的例子中,知道某個位址,就需要取得對應的Environment
常數。有多種選擇可以做到這一點。所有這些都需要enum
課程本身的改進。選項 1. 類別內枚舉。您需要建立一個方法來接受字串並將其與enum
類別的所有值進行比較。如果存在匹配,則該方法將返回所需的枚舉。對於我們的範例,我們需要Environment
在類別中建立以下方法:
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 + "]");
}
enum
然後我們可以這樣從字串中 得到:
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);
}
}
結論:
Environment name for url=[http://localhost:8080] is: DEV
這種方法有其缺點。每次,為了獲得enum
常數,您都必須迭代所有值並進行一定次數的比較。這種情況下的性能損失將由常量的數量和類似操作的數量決定。解決這個問題的第二種方法就不存在這個問題。完整Enum
類別代碼:
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 + "]");
}
}
選項 2:用法HashMap
在這種情況下,我們在枚舉中創建一個映射,並在編譯時填充它一次,然後從中獲取值:
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);
}
}
在使用方面,這兩個選項是相同的:
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);
}
}
結論:
Environment name for url=[http://localhost:8080] is: DEV
但這種方法也有缺點。首先,程式碼更多。其次,HashMap
所有enum
值都將永久儲存在應用程式記憶體中。正如你所看到的,一切都有優點和缺點。但考慮到enum
類別通常儲存的值並不多,因此缺點幾乎不明顯。有一個警告:如果經常執行這樣的操作(透過字串值取得 Java Enum),最好使用第二個選項。您可以在 JavaRush 課程中了解有關此主題和Enum
一般類別的更多資訊。Enum
學生們在第五級的第一堂課就已經學習了JavaRush 。
GO TO FULL VERSION