假设我有一个枚举
public enum Blah {
A, B, C, D
}
我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?
Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?
假设我有一个枚举
public enum Blah {
A, B, C, D
}
我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?
Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?
当前回答
我喜欢使用这种过程将命令作为字符串解析为枚举。我通常会将其中一个枚举设置为“未知”,因此当其他枚举未找到时(即使在不区分大小写的基础上)返回该枚举,而不是返回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;
}
其他回答
由于尚未提及交换机版本,我介绍了它(重用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)方法。
我的两分钱在这里:使用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注释处直接转换类型
我喜欢使用这种过程将命令作为字符串解析为枚举。我通常会将其中一个枚举设置为“未知”,因此当其他枚举未找到时(即使在不区分大小写的基础上)返回该枚举,而不是返回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;
}
public enum ToggleStatusUpdate {
OFF("off", 1),
ON("on", 2);
private final String name;
private final int position;
private ToggleStatusUpdate(String name, int position) {
this.name = name;
this.position = position;
}
public String getName() {
return name;
}
public int getPosition() {
return position;
}
public static int getPositionForName(String name) {
for(ToggleStatusUpdate toggleStatusUpdate : ToggleStatusUpdate.values()) {
if (toggleStatusUpdate.getName().equals(name)) {
return toggleStatusUpdate.getPosition();
}
}
return -1;
}
public static void main(String[] args) {
System.out.println(ToggleStatusUpdate.getPositionForName("off"));
}
}
这里有一个使用Guava库的解决方案。方法getPlanet()不区分大小写,因此getPlanet“MerCUrY”将返回Planet.MerCUrY。
package com.universe.solarsystem.planets;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Enums;
import com.google.common.base.Optional;
//Pluto and Eris are dwarf planets, who cares!
public enum Planet {
MERCURY,
VENUS,
EARTH,
MARS,
JUPITER,
SATURN,
URANUS,
NEPTUNE;
public static Planet getPlanet(String name) {
String val = StringUtils.trimToEmpty(name).toUpperCase();
Optional <Planet> possible = Enums.getIfPresent(Planet.class, val);
if (!possible.isPresent()) {
throw new IllegalArgumentException(val + "? There is no such planet!");
}
return possible.get();
}
}