How to get an enum value from a string value in Java?

前端 未结 27 2195
旧巷少年郎
旧巷少年郎 2020-11-21 10:53

Say I have an enum which is just

public enum Blah {
    A, B, C, D
}

and I would like to find the enum value of a string, for example

相关标签:
27条回答
  • 2020-11-21 11:44

    Solution using Guava libraries. Method getPlanet () is case insensitive, so getPlanet ("MerCUrY") will return Planet.MERCURY.

    package com.universe.solarsystem.planets;
    import org.apache.commons.lang3.StringUtils;
    import com.google.common.base.Enums;
    import com.google.common.base.Optional;
    
    //Pluto and Eris are dwarf planets, who cares!
    public enum Planet {
       MERCURY,
       VENUS,
       EARTH,
       MARS,
       JUPITER,
       SATURN,
       URANUS,
       NEPTUNE;
    
       public static Planet getPlanet(String name) {
          String val = StringUtils.trimToEmpty(name).toUpperCase();
          Optional <Planet> possible = Enums.getIfPresent(Planet.class, val);
          if (!possible.isPresent()) {
             throw new IllegalArgumentException(val + "? There is no such planet!");
          }
          return possible.get();
       }
    }
    
    0 讨论(0)
  • 2020-11-21 11:45

    Here's a nifty utility I use:

    /**
     * A common method for all enums since they can't have another base class
     * @param <T> Enum type
     * @param c enum type. All enums must be all caps.
     * @param string case insensitive
     * @return corresponding enum, or null
     */
    public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) {
        if( c != null && string != null ) {
            try {
                return Enum.valueOf(c, string.trim().toUpperCase());
            } catch(IllegalArgumentException ex) {
            }
        }
        return null;
    }
    

    Then in my enum class I usually have this to save some typing:

    public static MyEnum fromString(String name) {
        return getEnumFromString(MyEnum.class, name);
    }
    

    If your enums are not all caps, just change the Enum.valueOf line.

    Too bad I can't use T.class for Enum.valueOf as T is erased.

    0 讨论(0)
  • 2020-11-21 11:47

    Another way of doing this by using implicit static method name() of Enum. name will return the exact string used to create that enum which can be used to check against provided string:

    public enum Blah {
    
        A, B, C, D;
    
        public static Blah getEnum(String s){
            if(A.name().equals(s)){
                return A;
            }else if(B.name().equals(s)){
                return B;
            }else if(C.name().equals(s)){
                return C;
            }else if (D.name().equals(s)){
                return D;
            }
            throw new IllegalArgumentException("No Enum specified for this string");
        }
    }
    

    Testing:

    System.out.println(Blah.getEnum("B").name());

    //it will print B  B
    

    inspiration: 10 Examples of Enum in Java

    0 讨论(0)
  • 2020-11-21 11:47

    To add to the previous answers, and address some of the discussions around nulls and NPE I'm using Guava Optionals to handle absent/invalid cases. This works great for URI/parameter parsing.

    public enum E {
        A,B,C;
        public static Optional<E> fromString(String s) {
            try {
                return Optional.of(E.valueOf(s.toUpperCase()));
            } catch (IllegalArgumentException|NullPointerException e) {
                return Optional.absent();
            }
        }
    }
    

    For those not aware, here's some more info on avoiding null with Optional: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional

    0 讨论(0)
  • 2020-11-21 11:47

    As a switch-version has not been mentioned yet I introduce it (reusing OP's enum):

      private enum Blah {
        A, B, C, D;
    
        public static Blah byName(String name) {
          switch (name) {
            case "A":
              return A;
            case "B":
              return B;
            case "C":
              return C;
            case "D":
              return D;
            default:
              throw new IllegalArgumentException(
                "No enum constant " + Blah.class.getCanonicalName() + "." + name);
          }
        }
      }
    

    Since this don't give any additional value to the valueOf(String name) method, it only makes sense to define an additional method if we want have a different behavior. If we don't want to raise an IllegalArgumentException we can change the implementation to:

      private enum Blah {
        A, B, C, D;
    
        public static Blah valueOfOrDefault(String name, Blah defaultValue) {
          switch (name) {
            case "A":
              return A;
            case "B":
              return B;
            case "C":
              return C;
            case "D":
              return D;
            default:
              if (defaultValue == null) {
                throw new NullPointerException();
              }
              return defaultValue;
          }
        }
      }
    

    By providing a default value we keep the contract of Enum.valueOf(String name) without throwing an IllegalArgumentException in that manner that in no case null is returned. Therefore we throw a NullPointerException if the name is null and in case of default if defaultValue is null. That's how valueOfOrDefault works.

    This approach adopts the design of the Map-Interface which provides a method Map.getOrDefault(Object key, V defaultValue) as of Java 8.

    0 讨论(0)
  • 2020-11-21 11:48
    public static MyEnum getFromValue(String value) {
        MyEnum resp = null;
        MyEnum nodes[] = values();
        for(int i = 0; i < nodes.length; i++) {
            if(nodes[i].value.equals(value)) {
                resp = nodes[i];
                break;
            }
        }
        return resp;
    }
    
    0 讨论(0)
提交回复
热议问题