今天我们将讨论如何使用字符串枚举,更具体地说,如何
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