具有多个值的Java enum valueOf()?

具有多个值的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

我在Java中使用枚举时遇到了一个问题。 我已经阅读了有关为枚举分配值参数的文档。 但是,我的问题是,关于多重价值观,有可能吗

这就是我想要实现的目标: 我有一个语言的枚举。每种语言都由其名称和一些较短的别名表示(不总是,也不总是相同数量的别名)

以下是一个例子:

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;
  }
}