我怎样才能从它的string值查找Java枚举?

我想从它的string值(或可能的任何其他值)查找枚举。 我已经尝试了下面的代码,但它不允许静态初始化。 有一个简单的方法吗?

public enum Verbosity { BRIEF, NORMAL, FULL; private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>(); private Verbosity() { stringMap.put(this.toString(), this); } public static Verbosity getVerbosity(String key) { return stringMap.get(key); } }; 

使用为每个Enum自动创build的valueOf方法。

 Verbosity.valueOf("BRIEF") == Verbosity.BRIEF 

对于任意值,从下面开始:

 public static Verbosity findByAbbr(String abbr){ for(Verbosity v : values()){ if( v.abbr().equals(abbr)){ return v; } } return null; } 

如果你的分析器告诉你,稍后再继续执行Map实现。

我知道它遍历所有的值,但只有3枚枚举值是不值得任何其他的努力,事实上,除非你有很多的价值,我不会打扰一个地图它会足够快。

你很近 对于任意值,请尝试如下所示:

 public enum Day { MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"), THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ; private final String abbreviation; // Reverse-lookup map for getting a day from an abbreviation private static final Map<String, Day> lookup = new HashMap<String, Day>(); static { for (Day d : Day.values()) { lookup.put(d.getAbbreviation(), d); } } private Day(String abbreviation) { this.abbreviation = abbreviation; } public String getAbbreviation() { return abbreviation; } public static Day get(String abbreviation) { return lookup.get(abbreviation); } } 

@莱尔的回答是相当危险的,我看到它不工作,特别是如果你让枚举静态内部类。 相反,我使用了这样的东西,它将在枚举之前加载BootstrapSingleton映射。

使用现代JVM(JVM 1.6或更高版本) 编辑 这个问题不应该是一个问题,但是我认为JRebel仍然存在问题,但是我没有机会重新testing它

先载我

  public final class BootstrapSingleton { // Reverse-lookup map for getting a day from an abbreviation public static final Map<String, Day> lookup = new HashMap<String, Day>(); } 

现在将其加载到枚举构造函数中:

  public enum Day { MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"), THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ; private final String abbreviation; private Day(String abbreviation) { this.abbreviation = abbreviation; BootstrapSingleton.lookup.put(abbreviation, this); } public String getAbbreviation() { return abbreviation; } public static Day get(String abbreviation) { return lookup.get(abbreviation); } } 

如果你有一个内部枚举,你可以在枚举定义上面定义Map,并且(理论上)应该在之前加载。

你不能使用valueOf() ?

编辑:顺便说一句,没有什么阻止你在枚举中使用静态{}。

用Java 8你可以用这种方式实现:

 public static Verbosity findByAbbr(final String abbr){ return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null); } 

在Java语言规范7中有一个例子 ! 这反映了你用自引用初始化映射的问题。

也许,看看这个。 它为我工作。 这样做的目的是用'/ red_color'查找'RED'。 声明一个static map并将enum加载到它只有一次会带来一些性能优势,如果enum很多。

 public class Mapper { public enum Maps { COLOR_RED("/red_color", "RED"); private final String code; private final String description; private static Map<String, String> mMap; private Maps(String code, String description) { this.code = code; this.description = description; } public String getCode() { return name(); } public String getDescription() { return description; } public String getName() { return name(); } public static String getColorName(String uri) { if (mMap == null) { initializeMapping(); } if (mMap.containsKey(uri)) { return mMap.get(uri); } return null; } private static void initializeMapping() { mMap = new HashMap<String, String>(); for (Maps s : Maps.values()) { mMap.put(s.code, s.description); } } } } 

请把你的意见。

您可以将您的Enum定义为以下代码:

 public enum Verbosity { BRIEF, NORMAL, FULL, ACTION_NOT_VALID; private int value; public int getValue() { return this.value; } public static final Verbosity getVerbosityByValue(int value) { for(Verbosity verbosity : Verbosity.values()) { if(verbosity.getValue() == value) return verbosity ; } return ACTION_NOT_VALID; } @Override public String toString() { return ((Integer)this.getValue()).toString(); } }; 

请参阅以下链接了解更多信息

您可以使用上面的Gareth Davis&Brad Macebuild议的Enum::valueOf()函数,但要确保处理如果使用的string不在枚举中时将抛出的IllegalArgumentException