假设我有一个枚举
public enum Blah {
A, B, C, D
}
我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?
Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?
假设我有一个枚举
public enum Blah {
A, B, C, D
}
我想找到一个字符串的枚举值,例如“a”,它将是Blah.a。如何做到这一点?
Enum.valueOf()是我需要的方法吗?如果是,我将如何使用它?
当前回答
另一种实现方法是使用Enum的隐式静态方法name()。name将返回用于创建枚举的确切字符串,该枚举可用于对照提供的字符串进行检查:
public enum Blah {
A, B, C, D;
public static Blah getEnum(String s){
if(A.name().equals(s)){
return A;
}else if(B.name().equals(s)){
return B;
}else if(C.name().equals(s)){
return C;
}else if (D.name().equals(s)){
return D;
}
throw new IllegalArgumentException("No Enum specified for this string");
}
}
测试:
System.out.println(Blah.getEnum("B").name());
// It will print B B
灵感:Java中Enum的10个示例
其他回答
这里有一个使用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();
}
}
一种O(1)方法,灵感来自Thrift生成的代码,该代码使用哈希图。
public enum USER {
STUDENT("jon",0),TEACHER("tom",1);
private static final Map<String, Integer> map = new HashMap<>();
static {
for (USER user : EnumSet.allOf(USER.class)) {
map.put(user.getTypeName(), user.getIndex());
}
}
public static int findIndexByTypeName(String typeName) {
return map.get(typeName);
}
private USER(String typeName,int index){
this.typeName = typeName;
this.index = index;
}
private String typeName;
private int index;
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
获取enum名称的最快方法是在应用程序启动时创建enum文本和值的映射,并调用函数Blah.getEnumName()获取名称:
public enum Blah {
A("text1"),
B("text2"),
C("text3"),
D("text4");
private String text;
private HashMap<String, String> map;
Blah(String text) {
this.text = text;
}
public String getText() {
return this.text;
}
static{
createMapOfTextAndName();
}
public static void createMapOfTextAndName() {
map = new HashMap<String, String>();
for (Blah b : Blah.values()) {
map.put(b.getText(),b.name());
}
}
public static String getEnumName(String text) {
return map.get(text.toLowerCase());
}
}
由于尚未提及交换机版本,我介绍了它(重用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)方法。
Apache的commons-lang库有一个静态函数org.Apache.mons.lang3.EnumUtils.getEnum,它将字符串映射到Enum类型。基本上与杰弗里·郑的答案相同,但当它已经在野外时,不需要自己动手。