Java enum valueOf() with multiple values?

前端 未结 6 800
庸人自扰
庸人自扰 2020-12-07 16:34

I have a problem in Java using Enums. I have read the documentation about assigning value parameters to Enums. But, my question is what about multiple values, is it possible

6条回答
  •  遥遥无期
    2020-12-07 17:11

    Mapping a string to a enum value, is typically what the valueOf static method is doing for you. So if you want to accomplish this with the use of synonyms, you will have to develop something similar. However we do not want to give the presence that we can override a static method, so we just name it different for this purpose: fromString should be appropriate.

    public enum Language { 
      ENGLISH("eng", "en", "en_GB", "en_US"),   
      GERMAN("de", "ge"),   
      CROATIAN("hr", "cro"),   
      RUSSIAN("ru"),
      BELGIAN("be",";-)");
    
      static final private Map ALIAS_MAP = new HashMap(); 
      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 aliases; 
      private Language(String... aliases) { 
        this.aliases = Arrays.asList(aliases); 
      } 
    } 
    

    As a benefit of this type of implementation we can, as demonstrated, also easily implement the has static method to test if a given alias is part of the enum value set. At the same time, we applied some good naming conventions:

    • the enum values go in uppercase, to indicate that they are in actuality static finals (singleton instances).
    • at the same time, we also put all the other static finals all caps.

    Note that we do not have to repeat the name of the enum value itself: we always consider it's own name automatically (gets added to the ALIAS_MAP), and on top we normalize everything to uppercase to make it case insensitive.

    Seems big, but while using the enum, it looks pretty:

    public void main() {
      Language myLanguage = Language.fromString("en_GB");
      if (myLanguage == Language.ENGLISH) {
        System.out.println("Yes, I know, you understand English!");
      }
    } 
    

    The backing container for the aliases is a Map, a HashMap to be more specific. The HashMap provides a fast access path to the aliases, and is also easy to grow. Whenever we think about 'indexing' something, likely a HashMap should be our first choice.

    Note that for transparent use, we store both the name of the enum constant itself (retrieved through the name() method), and all the aliases. We could have implemented this differently by first attempting to do the lookup using the built-in valueOf static method. It is a design choice, but we would potentially have to deal with additional exceptions etc.

提交回复
热议问题