Скажем, у меня есть перечисление, которое просто
public enum Blah {
A, B, C, D
}
и я хотел бы найти значение перечисления строки, например, "A"
который будет Blah.A
. Как это было бы возможно сделать?
Является ли Enum.valueOf()
метод , который я нужен? Если так, как бы я использовал это?
Blah.valueOf("A")
метод чувствителен к регистру и не допускает посторонних пробелов, поэтому альтернативное решение, предложенное ниже @ JoséMi.toString()
значение, нет, я бы так не сказал.name()
вы получите фактическое имя константы enum, если вы не переопределите его.enum Blah {...}
определение не должно пытаться объявить свое собственное,values
ниvaluesOf
. Это похоже на то, как вы можете написать AnyTypeName.class, даже если вы никогда не объявляли переменную-член класса; компилятор делает все это просто работа. (Этот ответ может больше не быть полезным для вас через 3 месяца, но на всякий случай.)Другое решение, если текст не совпадает со значением перечисления:
источник
throw new IllegalArgumentException("No constant with text " + text + " found")
было бы лучше, чемreturn null
.Вот изящная утилита, которую я использую:
Затем в моем классе enum я обычно сохраняю набор текста:
Если ваши перечисления не все заглавные, просто измените
Enum.valueOf
строку.Жаль , я не могу использовать
T.class
для ,Enum.valueOf
какT
стирается.источник
Используйте образец из Джошуа Блоха, Эффективная Java :
(упрощено для краткости)
Также см:
Пример Oracle Java с использованием Enum и Map of instance
Порядок выполнения статических блоков в типе Enum
Как я могу найти перечисление Java из его значения String
источник
Stream.of(MyEnum.values()).collect(toMap(Enum::name, identity()))
я также рекомендую переопределить toString () (передаваемый через конструктор) и использовать его вместо имени, особенно если Enum связан с сериализуемыми данными, так как это позволяет вам управлять регистром без предоставления Сонар в припадке.unmodifiableMap
любом случае, то нет никакой пользы , начиная сConcurrentHashMap
. Просто используйтеHashMap
. (Если у вас есть гуава,ImmutableMap
то я бы порекомендовал это вместо этого!)ConcurrentHashMap
здесь, где карта никогда не изменяется после инициализации. Следовательно, почему даже, например, пример в самом JLS использует регулярныйHashMap
.Вы также должны быть осторожны с вашим делом. Позвольте мне объяснить: делать
Blah.valueOf("A")
дела, ноBlah.valueOf("a")
не будет работать. Тогда сноваBlah.valueOf("a".toUpperCase(Locale.ENGLISH))
будет работать.изменить
Изменено
toUpperCase
наtoUpperCase(Locale.ENGLISH)
основе тс. комментарий и документы Javaedit2 На Android вы должны использовать
Locale.US
, как указывает sulai .источник
Locale.US
для машиночитаемого ввода / вывода.Вот метод, который может сделать это для любого Enum и нечувствителен к регистру.
источник
equalsIgnoreCase
это путь. +1Использование
Blah.valueOf(string)
лучше, но вы также можете использоватьEnum.valueOf(Blah.class, string)
.источник
В Java 8 или более поздней версии , используя Streams :
источник
Если вы не хотите писать свою собственную утилиту, используйте Google гуайява библиотека:
В отличие от встроенной функции Java, она позволяет вам проверить, присутствует ли A в Blah и не выдает ли исключение.
источник
Мои 2 цента здесь: использование потоков Java8 + проверка точной строки:
** РЕДАКТИРОВАТЬ **
Переименовав функцию так, чтобы
fromString()
с тех пор как она была названа с использованием этого соглашения, вы получите некоторые преимущества от самого языка Java; например:источник
switch
блоки, вы можете.orElse(null)
вместо.orElseThrow()
этого кодировать исключение, выбрасываемое вdefault
предложении, и включать больше полезной информации, когда это необходимо. И чтобы сделать его более снисходительным, вы можете использоватьv -> Objects.equals(v.name, s == null ? "" : s.trim().toUpperCase())
Optional
изfindFirst()
, что позволяет пользователю решить , хочет ли он.orElse(null)
,orElseThrow()
или что - то ....public static MyEnum valueOf(String)
на самом деле является ошибкой компиляции, поскольку оно совпадает с неявно определенным, поэтому старая версия вашего ответа на самом деле лучше. ( JLS , ideone )Вам может понадобиться это:
Еще одно дополнение:
Это вернет вам значение по строковому имени Enum. Например, если вы укажете «PERSON» в fromEnumName, он вернет вам значение Enum, то есть «Person»
источник
Еще один способ сделать это с помощью неявного статического метода
name()
Enum. name возвращает точную строку, использованную для создания этого перечисления, которое можно использовать для проверки по предоставленной строке:Тестирование:
System.out.println(Blah.getEnum("B").name());
вдохновение: 10 примеров Enum на Java
источник
valueOf
что вам нужно. Этот статический метод не предлагает ничего лишнего, исключение и все такое. Тогда конструкции if / else очень опасны ... любая добавленная новая константа перечисления вызовет разрыв этого метода без изменений.name()
не является статичнымРешение с использованием библиотек Guava. Метод getPlanet () нечувствителен к регистру, поэтому getPlanet ("MerCUrY") вернет Planet.MERCURY.
источник
Чтобы добавить к предыдущим ответам и обсудить некоторые дискуссии вокруг нулей и NPE, я использую дополнительные возможности Guava для обработки отсутствующих / недействительных случаев. Это прекрасно работает для разбора URI / параметров.
Для тех, кто не знает, вот еще некоторая информация о том, как избежать нуля с помощью Необязательно: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional
источник
В Java 8 шаблон статической карты еще проще и является моим предпочтительным методом. Если вы хотите использовать Enum с Джексоном, вы можете переопределить toString и использовать его вместо имени, а затем аннотировать
@JsonValue
источник
источник
O (1) метод, основанный на сгенерированном коде, который использует хэш-карту.
источник
Enum очень полезен, я много использовал
Enum
для добавления описания некоторых полей на разных языках, как в следующем примере:И затем вы можете получить описание динамически на основе кода языка, переданного
getDescription(String lang)
методу, например:источник
Что о?
источник
java.lang.Enum
определяет несколько полезных методов, которые доступны для всех типов перечисления в Java:name()
метод, чтобы получить имя любой константы Enum. Строковый литерал, используемый для записи констант enum, является их именем.values()
метод можно использовать для получения массива всех констант Enum из типа Enum.valueOf()
метод для преобразования любой String в Enum константу в Java, как показано ниже.В этом фрагменте кода
valueOf()
метод возвращает константу Enum Gender.MALE, вызывающую имя для возвращаемого значения"MALE"
.источник
Библиотека Apache commons-lang имеет статическую функцию org.apache.commons.lang3.EnumUtils.getEnum, которая сопоставляет строку с вашим типом Enum. Тот же ответ, что и у Джеффриса, но зачем бросать свой, когда он уже в дикой природе.
источник
Добавление к ответу с самым высоким рейтингом, с полезной утилитой ...
valueOf()
выдает два разных исключения в тех случаях, когда ему не нравится его ввод.IllegalArgumentException
NullPointerExeption
Если ваши требования таковы, что у вас нет никаких гарантий, что ваша строка будет точно соответствовать значению перечисления, например, если данные строки поступают из базы данных и могут содержать старую версию перечисления, вам нужно будет обработать эти довольно часто...
Итак, вот метод многократного использования, который я написал, который позволяет нам определить Enum по умолчанию, который будет возвращен, если передаваемая строка не совпадает.
Используйте это так:
источник
Поскольку
switch
-версия еще не упоминалась, я представляю ее (повторно используя перечисление OP):Поскольку это не дает никакой дополнительной ценности
valueOf(String name)
методу, имеет смысл определять дополнительный метод, только если мы хотим иметь другое поведение. Если мы не хотим поднимать,IllegalArgumentException
мы можем изменить реализацию на:Предоставляя значение по умолчанию , мы соблюдаем контракт о
Enum.valueOf(String name)
не бросатьIllegalArgumentException
в такой манере , что ни в коем случаеnull
не возвращается. Поэтому мы бросаем,NullPointerException
если имяnull
и в случае,default
еслиdefaultValue
естьnull
. Вот так иvalueOfOrDefault
работает.Этот подход принимает дизайн
Map
-Interface, который обеспечивает методMap.getOrDefault(Object key, V defaultValue)
с Java 8.источник
Еще одна утилита захвата в обратном порядке. Использование значения, которое идентифицирует этот Enum, а не по его имени.
Пример:
EnumUtil.from(Foo.class, "drei")
возвращаетсяFoo.THREE
, потому что он будет использоватьgetValue
для сопоставления «drei», который является уникальным public, не final и не статическим методом в Foo. В случае , если Foo имеет более чем на общественном, а не окончательным и не статический метод, например,getTranslate
который возвращает «драй», другой метод может быть использован:EnumUtil.from(Foo.class, "drei", "getTranslate")
.источник
Kotlin Solution
Создайте расширение, а затем позвоните
valueOf<MyEnum>("value")
. Если тип недействителен, вы получите ноль и должны обработать егоКроме того, вы можете установить значение по умолчанию, вызывая
valueOf<MyEnum>("value", MyEnum.FALLBACK)
и избегая нулевого ответа. Вы можете расширить свой конкретный enum, чтобы по умолчанию он был автоматическимИли, если вы хотите оба, сделайте второе:
источник
Мне нравится использовать этот процесс для анализа команд в виде строк в перечислениях. У меня обычно одно из перечислений как «неизвестное», поэтому полезно возвращать его, когда другие не найдены (даже без учета регистра), а не ноль (это означает, что значения нет). Поэтому я использую этот подход.
источник
Самый быстрый способ получить имя enum - это создать карту текста и значения enum при запуске приложения и получить имя, вызвав функцию Blah.getEnumName ():
источник