在Java中如何从字符串值获取枚举值

在Java中如何从字符串值获取枚举值

技术背景

在Java编程中,枚举(Enum)是一种特殊的数据类型,它限制变量只能是预先定义好的值。有时候,我们需要将字符串转换为对应的枚举值,比如从用户输入、配置文件或网络传输中获取字符串,然后将其映射到相应的枚举实例。

实现步骤

1. 使用valueOf()方法

Enum类的valueOf()方法可以直接将字符串转换为枚举值,但要求字符串与枚举常量名完全匹配(包括大小写)。

1
2
3
4
5
6
7
8
9
10
enum Blah {
A, B, C, D;
}

public class Main {
public static void main(String[] args) {
Blah value = Blah.valueOf("A");
System.out.println(value);
}
}

2. 自定义查找方法

当字符串与枚举常量名不完全一致时,可以自定义方法进行查找。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public enum Blah {
A("text1"),
B("text2"),
C("text3"),
D("text4");

private String text;

Blah(String text) {
this.text = text;
}

public String getText() {
return this.text;
}

public static Blah fromString(String text) {
for (Blah b : Blah.values()) {
if (b.text.equalsIgnoreCase(text)) {
return b;
}
}
return null;
}
}

3. 使用静态Map

可以使用静态Map来提高查找效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
enum MyEnum {
ENUM_1("A"),
ENUM_2("B");

private String name;

private static final Map<String, MyEnum> ENUM_MAP;

MyEnum(String name) {
this.name = name;
}

public String getName() {
return this.name;
}

static {
Map<String, MyEnum> map = new ConcurrentHashMap<>();
for (MyEnum instance : MyEnum.values()) {
map.put(instance.getName().toLowerCase(), instance);
}
ENUM_MAP = Collections.unmodifiableMap(map);
}

public static MyEnum get(String name) {
return ENUM_MAP.get(name.toLowerCase());
}
}

4. 使用Java 8 Streams

在Java 8及以后的版本中,可以使用Stream API来简化查找过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Arrays;
import java.util.Optional;

public enum Blah {
A("text1"),
B("text2"),
C("text3"),
D("text4");

private String text;

Blah(String text) {
this.text = text;
}

public String getText() {
return this.text;
}

public static Optional<Blah> fromText(String text) {
return Arrays.stream(values())
.filter(bl -> bl.text.equalsIgnoreCase(text))
.findFirst();
}
}

核心代码

以下是一个综合示例,展示了多种获取枚举值的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import java.util.Arrays;
import java.util.Collections;
import java.util.ConcurrentHashMap;
import java.util.Map;
import java.util.Optional;

// 使用valueOf()方法
enum SimpleEnum {
VALUE1, VALUE2;
}

// 自定义查找方法
enum CustomEnum {
A("textA"),
B("textB");

private String text;

CustomEnum(String text) {
this.text = text;
}

public static CustomEnum fromString(String text) {
for (CustomEnum e : CustomEnum.values()) {
if (e.text.equals(text)) {
return e;
}
}
return null;
}
}

// 使用静态Map
enum MapEnum {
ENUM1("key1"),
ENUM2("key2");

private String key;
private static final Map<String, MapEnum> MAP;

static {
Map<String, MapEnum> map = new ConcurrentHashMap<>();
for (MapEnum e : MapEnum.values()) {
map.put(e.key, e);
}
MAP = Collections.unmodifiableMap(map);
}

MapEnum(String key) {
this.key = key;
}

public static MapEnum getByKey(String key) {
return MAP.get(key);
}
}

// 使用Java 8 Streams
enum StreamEnum {
ONE("one"),
TWO("two");

private String value;

StreamEnum(String value) {
this.value = value;
}

public static Optional<StreamEnum> fromValue(String value) {
return Arrays.stream(values())
.filter(e -> e.value.equals(value))
.findFirst();
}
}

public class EnumExample {
public static void main(String[] args) {
// 使用valueOf()方法
SimpleEnum simpleValue = SimpleEnum.valueOf("VALUE1");
System.out.println("SimpleEnum: " + simpleValue);

// 自定义查找方法
CustomEnum customValue = CustomEnum.fromString("textA");
System.out.println("CustomEnum: " + customValue);

// 使用静态Map
MapEnum mapValue = MapEnum.getByKey("key1");
System.out.println("MapEnum: " + mapValue);

// 使用Java 8 Streams
Optional<StreamEnum> streamValue = StreamEnum.fromValue("one");
streamValue.ifPresent(e -> System.out.println("StreamEnum: " + e));
}
}

最佳实践

  • 使用valueOf()方法:当字符串与枚举常量名完全匹配时,优先使用valueOf()方法,它简单直接。
  • 自定义查找方法:当字符串与枚举常量名不完全一致时,自定义查找方法可以灵活处理。
  • 使用静态Map:对于需要频繁查找的场景,使用静态Map可以提高查找效率。
  • 使用Java 8 Streams:在Java 8及以后的版本中,使用Stream API可以简化代码,提高代码的可读性。

常见问题

  • 大小写问题valueOf()方法要求字符串与枚举常量名大小写完全一致,否则会抛出IllegalArgumentException。可以使用toUpperCase()toLowerCase()方法进行大小写转换。
  • 空指针异常:在自定义查找方法中,如果没有找到匹配的枚举值,可能会返回null,需要注意空指针异常的处理。可以使用Optional类来避免空指针异常。
  • 性能问题:如果枚举值较多,使用简单的遍历查找可能会影响性能。可以使用静态Map或其他数据结构来提高查找效率。

在Java中如何从字符串值获取枚举值
https://119291.xyz/posts/2025-05-15.how-to-get-an-enum-value-from-a-string-value-in-java/
作者
ww
发布于
2025年5月15日
许可协议