假设我有一个枚举
public enum Blah {
A, B, C, D
}
我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?
Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?
假设我有一个枚举
public enum Blah {
A, B, C, D
}
我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?
Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?
当前回答
是的,Blah.valueOf(“A”)会给你Blah.A。
请注意,名称必须完全匹配,包括大小写:Blah.valueOf(“a”)和Blah.valueOf(“a”)都会引发IllegalArgumentException。
静态方法valueOf()和values()是在编译时创建的,不会出现在源代码中。不过,它们确实出现在Javadoc中;例如,Dialog.ModalityType显示了这两种方法。
其他回答
我正在寻找一个答案来查找“blah”名称,而不是其值(而不是文本)。根据马努的回答,我发现这段代码很有用:
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 valueOfCode(String blahCode) throws IllegalArgumentException {
Blah blah = Arrays.stream(Blah.values())
.filter(val -> val.name().equals(blahCode))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unable to resolve blah: " + blahCode));
return blah;
}
}
我喜欢使用这种过程将命令作为字符串解析为枚举。我通常会将其中一个枚举设置为“未知”,因此当其他枚举未找到时(即使在不区分大小写的基础上)返回该枚举,而不是返回null(这意味着没有值)。因此,我使用这种方法。
static <E extends Enum<E>> Enum getEnumValue(String what, Class<E> enumClass) {
Enum<E> unknown=null;
for (Enum<E> enumVal: enumClass.getEnumConstants()) {
if (what.compareToIgnoreCase(enumVal.name()) == 0) {
return enumVal;
}
if (enumVal.name().compareToIgnoreCase("unknown") == 0) {
unknown=enumVal;
}
}
return unknown;
}
我的两分钱在这里:使用Java 8 Streams并检查精确的字符串:
public enum MyEnum {
VALUE_1("Super"),
VALUE_2("Rainbow"),
VALUE_3("Dash"),
VALUE_3("Rocks");
private final String value;
MyEnum(String value) {
this.value = value;
}
/**
* @return the Enum representation for the given string.
* @throws IllegalArgumentException if unknown string.
*/
public static MyEnum fromString(String s) throws IllegalArgumentException {
return Arrays.stream(MyEnum.values())
.filter(v -> v.value.equals(s))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("unknown value: " + s));
}
}
我将函数重命名为fromString(),因为使用该约定命名它,您将从Java语言本身获得一些好处;例如:
在HeaderParam注释处直接转换类型
使用Streams的Java 8的答案和评论的组合。它创建了一个静态Map,用于使用默认值进行查找,以防止空检查。
public enum Blah {
A, B, C, D, INVALID
private static final Map<String, Blah> ENUM_MAP = Stream.of(Blah.values())
.collect(Collectors.toMap(Enum::name, Function.identity()));
public static Blah of(final String name) {
return ENUM_MAP.getOrDefault(name, INVALID);
}
}
// e.g.
Blah.of("A");
A
Blah.of("X")
INVALID
由于尚未提及交换机版本,我介绍了它(重用OP的枚举):
private enum Blah {
A, B, C, D;
public static Blah byName(String name) {
switch (name) {
case "A":
return A;
case "B":
return B;
case "C":
return C;
case "D":
return D;
default:
throw new IllegalArgumentException(
"No enum constant " + Blah.class.getCanonicalName() + "." + name);
}
}
}
由于这不会给valueOf(Stringname)方法提供任何附加值,因此只有在我们希望具有不同行为的情况下,才有必要定义一个附加方法。如果我们不想引发IllegalArgumentException,我们可以将实现更改为:
private enum Blah {
A, B, C, D;
public static Blah valueOfOrDefault(String name, Blah defaultValue) {
switch (name) {
case "A":
return A;
case "B":
return B;
case "C":
return C;
case "D":
return D;
default:
if (defaultValue == null) {
throw new NullPointerException();
}
return defaultValue;
}
}
}
通过提供默认值,我们保持Enum.valueOf(字符串名称)的约定,而不会以任何情况下都不会返回null的方式抛出IllegalArgumentException。因此,如果名称为null,我们将抛出NullPointerException,如果默认值为null,则抛出NullPointerException。这就是valueOfOrDefault的工作原理。
该方法采用了Map接口的设计,该接口提供了Java 8中的Map.getOrDefault(Object key,V defaultValue)方法。