具有多个值的Java enum valueOf()?
我在Java中使用枚举时遇到了一个问题。 我已经阅读了有关为枚举分配值参数的文档。 但是,我的问题是,关于多重价值观,有可能吗 这就是我想要实现的目标: 我有一个语言的枚举。每种语言都由其名称和一些较短的别名表示(不总是,也不总是相同数量的别名) 以下是一个例子:具有多个值的Java enum valueOf()?,java,enums,Java,Enums,我在Java中使用枚举时遇到了一个问题。 我已经阅读了有关为枚举分配值参数的文档。 但是,我的问题是,关于多重价值观,有可能吗 这就是我想要实现的目标: 我有一个语言的枚举。每种语言都由其名称和一些较短的别名表示(不总是,也不总是相同数量的别名) 以下是一个例子: public enum Language{ English("english", "eng", "en", "en_GB", "en_US"), German("german", "de", "ge"), Croatian("croa
public enum Language{
English("english", "eng", "en", "en_GB", "en_US"),
German("german", "de", "ge"),
Croatian("croatian", "hr", "cro"),
Russian("russian")
}
我可以这样定义一个枚举并通过调用Language.valueOf()来获得正确的枚举值吗?这可能与您试图实现的类似
public enum Language{
English("english", "eng", "en", "en_GB", "en_US"),
German("german", "de", "ge"),
Croatian("croatian", "hr", "cro"),
Russian("russian");
private final List<String> values;
Language(String ...values) {
this.values = Arrays.asList(values);
}
public List<String> getValues() {
return values;
}
}
简言之,没有
valueOf()方法的参数只能是枚举常量类型的字符串。因此它不能改变,也不能查找可能的值。看
您需要编写自己的实用程序方法来为给定的值返回正确的枚举类型。哇,非常快速的回答:)
谢谢各位
安迪是对的。我想调用Language.valueOf(“eng”)或Language.valueOf(“english”)并得到Language.english作为回报
我已经有了一个实用函数来实现这一点,但它不是很好。
开关函数,用于检查字符串值并返回相应的枚举实例
但是有很多代码重写(我有30-40种cca语言)。
如果我想添加一种语言,我必须将它添加到enum,并在实用程序类中实现一个新的检查
我试试弗拉维奥斯的方法。
只有一个问题。
你的构造函数,不是吗
Language(List<String> values) {
this.values = Arrays.asList(values);
}
语言(列出值){
this.values=Arrays.asList(值);
}
标准化数据:
public enum LanguageCode
{
ENGLISH,
GERMAN,
CROATIAN,
RUSSIAN,
// ...
}
// (add whatever initialization you want to that
然后
等等。将字符串映射到枚举值通常是
valueOf
静态方法为您所做的。因此,如果你想通过使用同义词来实现这一点,你必须开发类似的东西。因为我们不能重写静态方法,而且我认为在这种情况下我们不想重写,所以我们将对其进行不同的命名:fromString
应该是合适的
public enum Language {
ENGLISH("eng", "en", "en_GB", "en_US"),
GERMAN("de", "ge"),
CROATIAN("hr", "cro"),
RUSSIAN("ru"),
BELGIAN("be",";-)");
static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>();
static {
for (Language language:Language.values()) {
// ignoring the case by normalizing to uppercase
ALIAS_MAP.put(language.name().toUpperCase(),language);
for (String alias:language.aliases)
ALIAS_MAP.put(alias.toUpperCase(),language);
}
}
static public boolean has(String value) {
// ignoring the case by normalizing to uppercase
return ALIAS_MAP.containsKey(value.toUpperCase());
}
static public Language fromString(String value) {
if (value == null) throw new NullPointerException("alias null");
Language language = ALIAS_MAP.get(value.toUpperCase());
if (language == null)
throw new IllegalArgumentException("Not an alias: "+value);
return language;
}
private List<String> aliases;
private Language(String... aliases) {
this.aliases = Arrays.asList(aliases);
}
}
别名的备份容器是Map
,更具体地说是HashMap
。HashMap
提供了对别名的快速访问路径,并且易于扩展。每当我们想到“索引”某个东西时,我们的首选可能是HashMap
注意,为了透明使用,我们存储枚举常量本身的名称(通过
name()
方法检索)和所有别名。我们可以通过首先尝试使用内置的valueOf
static方法进行查找来实现这一点。这是一种设计选择,但我们可能必须处理其他异常等。或者添加一个方法,这样,如果结构更复杂,您的枚举和构造函数可以更干净:
public Language getLanguage(String code){
switch(code){
case "en":
case "en_GB":
...
case "eng":
return ENGLISH;
case "rus":
case "russian":
return RUSSIAN;
}
}
我可能误解了这一点,但我认为他希望能够使用Language.valueOf(“eng”)或Language.valueOf(“english”),并获得相同的enum实例;我编辑了答案,加入了一种获得这种效果的方法。是的,我也有点困惑,我真的认为这是一个聪明的想法,但不可能。你可以考虑的一些事情正在改变你的例子,以便它首先试图委托<>代码> Value(因此,覆盖了典型的“英语”),并且可能使用“代码>静态映射< /代码>而不是实例成员<代码>列表>代码>使查找更容易。
valueOf
方法仅适用于枚举的Java名称(即示例中的ENGLISH
)。对于这些情况,还必须使用find
方法。除非所有的函数都有一个值,但这是错误的帖子:)如果你使用你的构造函数(你必须删除Arrays.asList
调用以使其编译),那么实例必须用English(Arrays.asList(“English”、“eng”、“en”、“en\u GB”、“en\u US”)
创建。您还可以将值存储为简单数组而不是列表。。。不过搜索会有点尴尬。嗯……我认为这行不通。LanguageEnum成员将是英语、英语、英语、英语。。。而不是英语、德语……我建议你看看我的文章:虽然我不确定我是否完全理解你真正想要什么,但我相信至少有一篇文章包含了你问题的答案。
public enum Language {
ENGLISH("eng", "en", "en_GB", "en_US"),
GERMAN("de", "ge"),
CROATIAN("hr", "cro"),
RUSSIAN("ru"),
BELGIAN("be",";-)");
static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>();
static {
for (Language language:Language.values()) {
// ignoring the case by normalizing to uppercase
ALIAS_MAP.put(language.name().toUpperCase(),language);
for (String alias:language.aliases)
ALIAS_MAP.put(alias.toUpperCase(),language);
}
}
static public boolean has(String value) {
// ignoring the case by normalizing to uppercase
return ALIAS_MAP.containsKey(value.toUpperCase());
}
static public Language fromString(String value) {
if (value == null) throw new NullPointerException("alias null");
Language language = ALIAS_MAP.get(value.toUpperCase());
if (language == null)
throw new IllegalArgumentException("Not an alias: "+value);
return language;
}
private List<String> aliases;
private Language(String... aliases) {
this.aliases = Arrays.asList(aliases);
}
}
public void main() {
Language myLanguage = Language.fromString("en_GB");
if (myLanguage == Language.ENGLISH) {
System.out.println("Yes, I know, you understand English!");
}
}
public Language getLanguage(String code){
switch(code){
case "en":
case "en_GB":
...
case "eng":
return ENGLISH;
case "rus":
case "russian":
return RUSSIAN;
}
}