присвоить - сравнение enum java




Как получить значение перечисления из строкового значения в Java? (16)

Скажем, у меня есть перечисление, которое просто

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

и я хотел бы найти значение перечисления строки, например "A" которое будет Blah.A Как это можно сделать?

Enum.valueOf() ли метод Enum.valueOf() ? Если да, то как я буду использовать это?


O (1), основанный на извлеченном сгенерированном коде, который использует хэш-карту.

public enum USER {
        STUDENT("jon",0),TEACHER("tom",1);

        private static final Map<String, Integer> map = new HashMap<>();

        static {
                for (USER user : EnumSet.allOf(USER.class)) {
                        map.put(user.getTypeName(), user.getIndex());
                }
        }

        public static int findIndexByTypeName(String typeName) {
                return map.get(typeName);
        }

        private USER(String typeName,int index){
                this.typeName = typeName;
                this.index = index;
        }
        private String typeName;
        private int index;
        public String getTypeName() {
                return typeName;
        }
        public void setTypeName(String typeName) {
                this.typeName = typeName;
        }
        public int getIndex() {
                return index;
        }
        public void setIndex(int index) {
                this.index = index;
        }

}

Библиотека commons-lang Apache имеет статическую функцию org.apache.commons.lang3.EnumUtils.getEnum которая будет отображать строку в ваш тип Enum. Тот же ответ по существу, что и Geoffreys, но зачем катиться самостоятельно, когда он уже находится в дикой природе.


В Java 8 статический шаблон карты еще проще и мой предпочтительный метод. Если вы хотите использовать Enum с Jackson, вы можете переопределить toString и использовать это вместо имени, а затем аннотировать с помощью @JsonValue

public enum MyEnum {
    BAR,
    BAZ;
    private static final Map<String, MyEnum> MAP = Stream.of(MyEnum.values()).collect(Collectors.toMap(Enum::name, Function.identity()));
    public static MyEnum fromName(String name){
        return MAP.get(name);
    }
}

public enum MyEnumForJson {
    BAR("bar"),
    BAZ("baz");
    private static final Map<String, MyEnumForJson> MAP = Stream.of(MyEnumForJson.values()).collect(Collectors.toMap(Object::toString, Function.identity()));
    private final String value;

    MyEnumForJson(String value) {
        this.value = value;
    }

    @JsonValue
    @Override
    public String toString() {
        return value;
    }

    public static MyEnumForJson fromValue(String value){
        return MAP.get(value);
    }
}

Вам может понадобиться следующее:

public enum ObjectType {
    PERSON("Person");

    public String parameterName;

    ObjectType(String parameterName) {
        this.parameterName = parameterName;
    }

    public String getParameterName() {
        return this.parameterName;
    }

    //From String method will return you the Enum for the provided input string
    public static ObjectType fromString(String parameterName) {
        if (parameterName != null) {
            for (ObjectType objType : ObjectType.values()) {
                if (parameterName.equalsIgnoreCase(objType.parameterName)) {
                    return objType;
                }
            }
        }
        return null;
    }
}

Еще одно дополнение:

   public static String fromEnumName(String parameterName) {
        if (parameterName != null) {
            for (DQJ objType : DQJ.values()) {
                if (parameterName.equalsIgnoreCase(objType.name())) {
                    return objType.parameterName;
                }
            }
        }
        return null;
    }

Это вернет вам значение с помощью стробированного имени перечисления. Например, если вы предоставили «ЧЕЛОВЕК» в fromEnumName, он вернет вам значение Enum, то есть «Person»,


Вот полезная утилита, которую я использую:

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

Затем в моем классе enum я обычно сохраняю некоторую типизацию:

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

Если ваши перечисления не все шапки, просто измените строку Enum.valueOf .

Слишком плохо, я не могу использовать T.class для Enum.valueOf поскольку T стирается.


Вы также должны быть осторожны с вашим делом. Позвольте мне объяснить: выполнение Blah.valueOf("A") работает, но Blah.valueOf("a") не будет работать. Затем снова будет Blah.valueOf("a".toUpperCase(Locale.ENGLISH)) .

редактировать
Изменен toUpperCase на toUpperCase(Locale.ENGLISH) на основе tc. комментарий и java-документы

edit2 На андроиде вы должны использовать Locale.US , как указывает сулай .


Добавляя к высокому рейтингу ответ, с полезной утилитой ...

valueOf() выбрасывает два разных Исключения в случаях, когда ему не нравится его ввод.

  • IllegalArgumentException
  • NullPointerExeption

Если ваши требования таковы, что у вас нет гарантии, что ваша строка определенно будет соответствовать значению перечисления, например, если данные String поступают из базы данных и могут содержать старую версию перечисления, тогда вам нужно будет обрабатывать эти довольно часто...

Итак, вот метод многократного использования, который я написал, который позволяет нам определить возвращаемый по умолчанию Enum, если String, который мы передаем, не соответствует.

private static <T extends Enum<T>> T valueOf( String name , T defaultVal) {
        try {
            return Enum.valueOf(defaultVal.getDeclaringClass() , name);
        } catch (IllegalArgumentException | NullPointerException e) {
            return defaultVal;
        }
    }

Используйте его так:

public enum MYTHINGS {
    THINGONE,
    THINGTWO
}

public static void main(String [] asd) {
  valueOf("THINGTWO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGTWO
  valueOf("THINGZERO" , MYTHINGS.THINGONE);//returns MYTHINGS.THINGONE
}

Другая утилита записывается обратным образом. Используя значение, которое идентифицирует Enum, а не его имя.

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.EnumSet;

public class EnumUtil {

    /**
     * Returns the <code>Enum</code> of type <code>enumType</code> whose a 
     * public method return value of this Enum is 
     * equal to <code>valor</code>.<br/>
     * Such method should be unique public, not final and static method 
     * declared in Enum.
     * In case of more than one method in match those conditions
     * its first one will be chosen.
     * 
     * @param enumType
     * @param value
     * @return 
     */
    public static <E extends Enum<E>> E from(Class<E> enumType, Object value) {
        String methodName = getMethodIdentifier(enumType);
        return from(enumType, value, methodName);
    }

    /**
     * Returns the <code>Enum</code> of type <code>enumType</code> whose  
     * public method <code>methodName</code> return is 
     * equal to <code>value</code>.<br/>
     *
     * @param enumType
     * @param value
     * @param methodName
     * @return
     */
    public static <E extends Enum<E>> E from(Class<E> enumType, Object value, String methodName) {
        EnumSet<E> enumSet = EnumSet.allOf(enumType);
        for (E en : enumSet) {
            try {
                String invoke = enumType.getMethod(methodName).invoke(en).toString();
                if (invoke.equals(value.toString())) {
                    return en;
                }
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

    private static String getMethodIdentifier(Class<?> enumType) {
        Method[] methods = enumType.getDeclaredMethods();
        String name = null;
        for (Method method : methods) {
            int mod = method.getModifiers();
            if (Modifier.isPublic(mod) && !Modifier.isStatic(mod) && !Modifier.isFinal(mod)) {
                name = method.getName();
                break;
            }
        }
        return name;
    }
}

Пример:

public enum Foo {
    ONE("eins"), TWO("zwei"), THREE("drei");

    private String value;

    private Foo(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

EnumUtil.from(Foo.class, "drei") возвращает Foo.THREE , потому что он будет использовать getValue для соответствия «drei», который является уникальным публичным, а не конечным, а не статическим методом в Foo. В случае, если Foo имеет больше, чем публичный, а не конечный и не статический метод, например, getTranslate который возвращает «drei», можно использовать другой метод: EnumUtil.from(Foo.class, "drei", "getTranslate") .


Другой способ сделать это, используя неявное статическое name() метода name() для Enum. name вернет точную строку, используемую для создания этого перечисления, которое может использоваться для проверки с предоставленной строкой:

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

Тестирование:

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

//it will print B  B

вдохновение: 10 примеров Enum в Java


Если вы не хотите писать свою собственную утилиту, используйте библиотеку guava Google:

Enums.getIfPresent(Blah.class, "A")

В отличие от встроенной функции java, давайте проверим, присутствует ли A в Blah и не генерирует исключение.


Как насчет?

public enum MyEnum {
    FIRST,
    SECOND,
    THIRD;

    public static Optional<MyEnum> fromString(String value){
        try{
            return Optional.of(MyEnum.valueOf(value));
        }catch(Exception e){
            return Optional.empty();
        }
    }
}

Мне нравится использовать этот процесс для анализа команд как строк в перечислениях. Обычно у меня есть одно из перечислений как «неизвестное», поэтому оно помогает вернуть это, когда другие не найдены (даже на основе без учета регистра), а не в нуле (это означает, что нет значения). Поэтому я использую этот подход.

static <E extends Enum<E>> Enum getEnumValue(String what, Class<E> enumClass) {
    Enum<E> unknown=null;
    for (Enum<E> enumVal: enumClass.getEnumConstants()) {  
        if (what.compareToIgnoreCase(enumVal.name()) == 0) {
            return enumVal;
        }
        if (enumVal.name().compareToIgnoreCase("unknown") == 0) {
            unknown=enumVal;
        }
    }  
    return unknown;
}

Поскольку switch -version еще не упоминается, я ввожу его (повторное использование перечисления OP):

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

Поскольку это не дает никакого дополнительного значения методу valueOf(String name) , имеет смысл только определить дополнительный метод, если мы хотим иметь другое поведение. Если мы не хотим поднимать IllegalArgumentException мы можем изменить реализацию:

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

Предоставляя значение по умолчанию, мы сохраняем contract Enum.valueOf(String name) не бросая IllegalArgumentException таким образом, чтобы ни в коем случае не возвращался null . Поэтому мы бросаем NullPointerException если имя имеет значение null и в случае default если defaultValue равно null . Вот как работает valueOfOrDefault .

Этот подход использует дизайн Map -Interface, который предоставляет метод Map.getOrDefault(Object key, V defaultValue) с Java 8.


Решение с использованием библиотек Guava. Метод getPlanet () нечувствителен к регистру, поэтому getPlanet («MerCUrY») вернет 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();
   }
}

Blah.valueOf(string) использовать Blah.valueOf(string) но вы также можете использовать Enum.valueOf(Blah.class, string) .


java.lang.Enum определяет несколько полезных методов, которые доступны для всех типов перечисления в Java:

  • Вы можете использовать метод name() для получения имен любых констант Enum. Строковым литералом, используемым для записи констант перечисления, является их имя.
  • Аналогично метод values() может использоваться для получения массива всех констант Enum из типа Enum.
  • И для заданного вопроса вы можете использовать метод valueOf() для преобразования константы String в Enum в Java, как показано ниже.
public class EnumDemo06 {
    public static void main(String args[]) {
        Gender fromString = Gender.valueOf("MALE");
        System.out.println("Gender.MALE.name() : " + fromString.name());
    }

    private enum Gender {
        MALE, FEMALE;
    }
}

Output:
Gender.MALE.name() : MALE

В этом фрагменте кода метод valueOf() возвращает константу Enum Gender.MALE, вызывающее имя на которой возвращает "MALE" .







enums