I would like to lookup an enum from its string value (or possibly any other value). I've tried the following code but it doesn't allow static in initialisers. Is there a simple way?
我希望从它的字符串值(或任何其他值)查找enum。我尝试过以下代码,但它不允许在初始化器中使用静态。有简单的方法吗?
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);
}
};
10 个解决方案
#1
178
Use the valueOf
method which is automatically created for each Enum.
使用为每个枚举自动创建的valueOf方法。
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
For arbitrary values start with:
对于任意值,以:
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
Only move on later to Map implementation if your profiler tells you to.
如果您的分析器告诉您,请稍后再进行映射实现。
I know it's iterating over all the values, but with only 3 enum values it's hardly worth any other effort, in fact unless you have a lot of values I wouldn't bother with a Map it'll be fast enough.
我知道它遍历了所有的值,但是只有3 enum值,它几乎不值得做任何其他的努力,事实上,除非你有很多值,否则我不会用映射来麻烦它会足够快。
#2
105
You're close. For arbitrary values, try something like the following:
你关闭。对于任意值,可以尝试如下方法:
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);
}
}
#3
12
@Lyle's answer is rather dangerous and I have seen it not work particularly if you make the enum a static inner class. Instead I have used something like this which will load the BootstrapSingleton maps before the enums.
@Lyle的答案相当危险,我认为如果你把enum设定为静态内部类,它不会起作用。相反,我使用了类似的东西,它将在枚举之前加载BootstrapSingleton映射。
Edit this should not be a problem any more with modern JVMs (JVM 1.6 or greater) but I do think there are still issues with JRebel but I haven't had a chance to retest it.
对于现代JVM (JVM 1.6或更高)来说,编辑这个应该不再是个问题,但我认为JRebel仍然存在问题,但我还没有机会重新测试它。
Load me first:
负载我先:
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>();
}
Now load it in the enum constructor:
现在在enum构造函数中加载它:
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);
}
}
If you have an inner enum you can just define the Map above the enum definition and that (in theory) should get loaded before.
如果您有一个内部enum,您可以在enum定义之上定义映射,并且(理论上)应该在此之前加载。
#4
6
And you can't use valueOf()?
你不能使用valueOf()?
Edit: Btw, there is nothing stopping you from using static { } in an enum.
编辑:顺便说一句,在enum中使用静态{}没有什么可以阻止您的。
#5
5
with Java 8 you can achieve with this way:
使用Java 8,您可以通过以下方式实现:
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
#6
4
In the Java Language Specification 7 there is an a example! that reflects your question on initialization of the map with self-references.
在Java语言规范中有一个例子!这反映了您的问题,在初始化的地图与自我参考。
#7
2
In case it helps others, the option I prefer, which is not listed here, uses Guava's Maps functionality:
为了帮助其他人,我喜欢的选项(这里没有列出)使用了番石榴的地图功能:
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);
}
}
With the default you can use null
, you can throw IllegalArgumentException
or your fromString
could return an Optional
, whatever behavior you prefer.
默认情况下,您可以使用null,可以抛出IllegalArgumentException,或者您的fromString可以返回一个可选的、您喜欢的任何行为。
#8
1
Perhaps, take a look at this. Its working for me. The purpose of this is to lookup 'RED' with '/red_color'. Declaring a static map
and loading the enum
s into it only once would bring some performance benefits if the enum
s are many.
也许,看看这个。它为我工作。它的目的是用'/red_color'查找'RED'。如果枚举数很多,那么声明静态映射并只将枚举加载到其中一次将带来一些性能优势。
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);
}
}
}
}
Please put in your opinons.
请把你的眼镜戴上。
#9
0
You can define your Enum as following code :
您可以将枚举定义为以下代码:
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();
}
};
See following link for more clarification
请参阅下面的链接以了解更多的说明
#10
-2
You can use the Enum::valueOf()
function as suggested by Gareth Davis & Brad Mace above, but make sure you handle the IllegalArgumentException
that would be thrown if the string used is not present in the enum.
您可以使用上面Gareth Davis和Brad Mace建议的Enum: valueOf()函数,但是请确保您处理了IllegalArgumentException,如果所使用的字符串不在Enum中,则将抛出该异常。
#1
178
Use the valueOf
method which is automatically created for each Enum.
使用为每个枚举自动创建的valueOf方法。
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
For arbitrary values start with:
对于任意值,以:
public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
Only move on later to Map implementation if your profiler tells you to.
如果您的分析器告诉您,请稍后再进行映射实现。
I know it's iterating over all the values, but with only 3 enum values it's hardly worth any other effort, in fact unless you have a lot of values I wouldn't bother with a Map it'll be fast enough.
我知道它遍历了所有的值,但是只有3 enum值,它几乎不值得做任何其他的努力,事实上,除非你有很多值,否则我不会用映射来麻烦它会足够快。
#2
105
You're close. For arbitrary values, try something like the following:
你关闭。对于任意值,可以尝试如下方法:
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);
}
}
#3
12
@Lyle's answer is rather dangerous and I have seen it not work particularly if you make the enum a static inner class. Instead I have used something like this which will load the BootstrapSingleton maps before the enums.
@Lyle的答案相当危险,我认为如果你把enum设定为静态内部类,它不会起作用。相反,我使用了类似的东西,它将在枚举之前加载BootstrapSingleton映射。
Edit this should not be a problem any more with modern JVMs (JVM 1.6 or greater) but I do think there are still issues with JRebel but I haven't had a chance to retest it.
对于现代JVM (JVM 1.6或更高)来说,编辑这个应该不再是个问题,但我认为JRebel仍然存在问题,但我还没有机会重新测试它。
Load me first:
负载我先:
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>();
}
Now load it in the enum constructor:
现在在enum构造函数中加载它:
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);
}
}
If you have an inner enum you can just define the Map above the enum definition and that (in theory) should get loaded before.
如果您有一个内部enum,您可以在enum定义之上定义映射,并且(理论上)应该在此之前加载。
#4
6
And you can't use valueOf()?
你不能使用valueOf()?
Edit: Btw, there is nothing stopping you from using static { } in an enum.
编辑:顺便说一句,在enum中使用静态{}没有什么可以阻止您的。
#5
5
with Java 8 you can achieve with this way:
使用Java 8,您可以通过以下方式实现:
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
#6
4
In the Java Language Specification 7 there is an a example! that reflects your question on initialization of the map with self-references.
在Java语言规范中有一个例子!这反映了您的问题,在初始化的地图与自我参考。
#7
2
In case it helps others, the option I prefer, which is not listed here, uses Guava's Maps functionality:
为了帮助其他人,我喜欢的选项(这里没有列出)使用了番石榴的地图功能:
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);
}
}
With the default you can use null
, you can throw IllegalArgumentException
or your fromString
could return an Optional
, whatever behavior you prefer.
默认情况下,您可以使用null,可以抛出IllegalArgumentException,或者您的fromString可以返回一个可选的、您喜欢的任何行为。
#8
1
Perhaps, take a look at this. Its working for me. The purpose of this is to lookup 'RED' with '/red_color'. Declaring a static map
and loading the enum
s into it only once would bring some performance benefits if the enum
s are many.
也许,看看这个。它为我工作。它的目的是用'/red_color'查找'RED'。如果枚举数很多,那么声明静态映射并只将枚举加载到其中一次将带来一些性能优势。
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);
}
}
}
}
Please put in your opinons.
请把你的眼镜戴上。
#9
0
You can define your Enum as following code :
您可以将枚举定义为以下代码:
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();
}
};
See following link for more clarification
请参阅下面的链接以了解更多的说明
#10
-2
You can use the Enum::valueOf()
function as suggested by Gareth Davis & Brad Mace above, but make sure you handle the IllegalArgumentException
that would be thrown if the string used is not present in the enum.
您可以使用上面Gareth Davis和Brad Mace建议的Enum: valueOf()函数,但是请确保您处理了IllegalArgumentException,如果所使用的字符串不在Enum中,则将抛出该异常。