pet*_*ust 147 java lookup enums
我想从其字符串值(或可能是任何其他值)查找枚举.我尝试了以下代码,但它不允许在初始化程序中使用静态代码.有一个简单的方法吗?
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);
}
};
Run Code Online (Sandbox Code Playgroud)
Gar*_*vis 219
使用valueOf
为每个枚举自动创建的方法.
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
Run Code Online (Sandbox Code Playgroud)
对于任意值,请以:
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果您的探查器告诉您,请稍后再转到Map实现.
我知道它正在迭代所有的值,但只有3个枚举值,这几乎不值得任何其他努力,事实上,除非你有很多值我不打扰地图它会足够快.
Lyl*_*yle 127
你很亲密 对于任意值,请尝试以下操作:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 18
使用Java 8,您可以通过以下方式实现:
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
Run Code Online (Sandbox Code Playgroud)
Ada*_*ent 13
@Lyle的回答是相当危险的,我已经看到它不起作用,特别是如果你让enum成为一个静态的内部类.相反,我使用了类似的东西,它将在枚举之前加载BootstrapSingleton地图.
编辑 这个应该不再是现代JVM(JVM 1.6或更高版本)的问题,但我认为JRebel仍然存在问题,但我没有机会重新测试它.
首先加载我:
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>();
}
Run Code Online (Sandbox Code Playgroud)
现在将它加载到枚举构造函数中:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你有一个内部枚举,你可以在枚举定义之上定义Map,并且(理论上)之前应该加载.
从 java 8 开始,您可以在一行中初始化地图,而无需静态块
private static Map<String, Verbosity> stringMap = Arrays.stream(values())
.collect(Collectors.toMap(Enum::toString, Function.identity()));
Run Code Online (Sandbox Code Playgroud)
小智 6
public enum EnumRole {
ROLE_ANONYMOUS_USER_ROLE ("anonymous user role"),
ROLE_INTERNAL ("internal role");
private String roleName;
public String getRoleName() {
return roleName;
}
EnumRole(String roleName) {
this.roleName = roleName;
}
public static final EnumRole getByValue(String value){
return Arrays.stream(EnumRole.values()).filter(enumRole -> enumRole.roleName.equals(value)).findFirst().orElse(ROLE_ANONYMOUS_USER_ROLE);
}
public static void main(String[] args) {
System.out.println(getByValue("internal role").roleName);
}
Run Code Online (Sandbox Code Playgroud)
}
为了帮助其他人,我更喜欢的选项(未在此处列出)使用了Guava的Maps功能:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
使用默认值,您可以使用null
,可以throw IllegalArgumentException
或fromString
可以返回Optional
,无论您喜欢哪种行为。