How can I lookup a Java enum from its String value?
我想从枚举的字符串值(或者可能是任何其他值)中查找枚举。我已经尝试了以下代码,但它不允许在初始化器中使用静态代码。有简单的方法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
使用为每个枚举自动创建的
1 | Verbosity.valueOf("BRIEF") == Verbosity.BRIEF |
对于任意值,从以下值开始:
1 2 3 4 5 6 7 8 | public static Verbosity findByAbbr(String abbr){ for(Verbosity v : values()){ if( v.abbr().equals(abbr)){ return v; } } return null; } |
只有在分析器告诉您以后才能继续映射实现。
我知道它在迭代所有的值,但是只有3个枚举值,它几乎不值得做任何其他的工作,事实上,除非你有很多值,否则我不会为一个映射而烦恼,它将足够快。
你离我很近。对于任意值,请尝试如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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); } } |
用Java 8可以用这种方式实现:
1 2 3 |
@Lyle的答案相当危险,我已经看到它不起作用,特别是如果您使枚举成为一个静态的内部类。相反,我使用了这样的方法,它将在枚举之前加载bootstrapsingleton映射。
编辑这应该不再是现代JVM(JVM 1.6或更高版本)的问题,但我认为JREBEL仍然存在问题,但我没有机会重新测试它。
先载我:
1 2 3 4 5 |
现在将其加载到枚举构造函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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); } } |
如果您有一个内部枚举,那么您只需定义枚举定义上方的映射,并且(理论上)应该在加载之前就完成了。
您不能使用valueof()?
编辑:顺便说一句,没有什么能阻止您在枚举中使用static。
在Java语言规范7中有一个例子!这反映了您关于用自引用初始化映射的问题。
如果它能帮助其他人,我喜欢的选项(这里没有列出)使用了番石榴的地图功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public enum Vebosity { BRIEF("BRIEF"), NORMAL("NORMAL"), FULL("FULL"); private String value; private Verbosity(final String value) { this.value = value; } public String getValue() { return this.value; } private static ImmutableMap<String, Verbosity> reverseLookup = Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue); public static Verbosity fromString(final String id) { return reverseLookup.getOrDefault(id, NORMAL); } } |
默认情况下,您可以使用
也许,看看这个。这对我很有效。这样做的目的是查找"红色"和"/red"颜色。如果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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); } } } } |
请把你的鸦片片放进去。
由于Java 8,您可以在单行中初始化映射,而无需静态块。
1 2 |
可以将枚举定义为以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 mace建议的