在 Javaenum 中重写 valueof()和 toString()

我的 enum中的值是需要有空格的单词,但枚举不能在它们的值中有空格,所以它们都被打包了。我想覆盖 toString(),在我告诉它的地方添加这些空格。

我还希望枚举在我将空格添加到的同一个字符串上使用 valueOf()时提供正确的枚举。

例如:

public enum RandomEnum
{
StartHere,
StopHere
}

对值为 StartHereRandomEnum调用 toString()返回字符串 "Start Here"。对同一个字符串("Start Here")调用 valueof()将返回枚举值 StartHere

我怎么能这么做?

182006 次浏览

我不认为你能让 value Of (“ Start Here”)起作用。 但至于空间... 试试下面的..。

static private enum RandomEnum {
R("Start There"),
G("Start Here");
String value;
RandomEnum(String s) {
value = s;
}
}


System.out.println(RandomEnum.G.value);
System.out.println(RandomEnum.valueOf("G").value);


Start Here
Start Here

你可以试试这个代码。由于不能覆盖 valueOf方法,因此必须定义一个自定义方法(下面示例代码中的 getEnum) ,该方法返回所需的值,并更改客户端以使用此方法。

public enum RandomEnum {


StartHere("Start Here"),
StopHere("Stop Here");


private String value;


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


public String getValue() {
return value;
}


@Override
public String toString() {
return this.getValue();
}


public static RandomEnum getEnum(String value) {
for(RandomEnum v : values())
if(v.getValue().equalsIgnoreCase(value)) return v;
throw new IllegalArgumentException();
}
}

下面是 valueOf ()的一个很好的通用替代品

public static RandomEnum getEnum(String value) {
for (RandomEnum re : RandomEnum.values()) {
if (re.description.compareTo(value) == 0) {
return re;
}
}
throw new IllegalArgumentException("Invalid RandomEnum value: " + value);
}

您可以在枚举中使用静态 Map,将 String 映射到枚举常量。在‘ getEnum’静态方法中使用它。这就省略了每次希望从它的 String 值中获取枚举时迭代枚举的需要。

public enum RandomEnum {


StartHere("Start Here"),
StopHere("Stop Here");


private final String strVal;
private RandomEnum(String strVal) {
this.strVal = strVal;
}


public static RandomEnum getEnum(String strVal) {
if(!strValMap.containsKey(strVal)) {
throw new IllegalArgumentException("Unknown String Value: " + strVal);
}
return strValMap.get(strVal);
}


private static final Map<String, RandomEnum> strValMap;
static {
final Map<String, RandomEnum> tmpMap = Maps.newHashMap();
for(final RandomEnum en : RandomEnum.values()) {
tmpMap.put(en.strVal, en);
}
strValMap = ImmutableMap.copyOf(tmpMap);
}


@Override
public String toString() {
return strVal;
}
}

只需确保映射的静态初始化发生在枚举常量的声明之下。

顺便说一句,‘ ImmutableMap’类型来自于 Google 的番石榴 API,在这种情况下我绝对推荐它。


编辑-根据评论:

  1. 此解决方案假定每个分配的字符串值都是唯一且非空的。假设枚举的创建者可以控制它,并且字符串对应于惟一的 & 非空枚举值,那么这似乎是一个安全的限制。
  2. 我按照问题中的要求添加了‘ toString ()’方法

试试这个,但我不确定它是否适用于任何地方:)

public enum MyEnum {
A("Start There"),
B("Start Here");


MyEnum(String name) {
try {
Field fieldName = getClass().getSuperclass().getDeclaredField("name");
fieldName.setAccessible(true);
fieldName.set(this, name);
fieldName.setAccessible(false);
} catch (Exception e) {}
}
}

Java8实现怎么样? (null 可以替换为默认的 Enum)

public static RandomEnum getEnum(String value) {
return Arrays.stream(RandomEnum.values()).filter(m -> m.value.equals(value)).findAny().orElse(null);
}

或者你可以用:

...findAny().orElseThrow(NotFoundException::new);

您仍然可以在枚举中实现以下选项:

public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name){...}