我怎样才能从它的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
。