Java: Проверьте, содержит ли перечисление заданную строку?
Здесь моя проблема - я ищу (если он вообще существует) перечислимый эквивалент ArrayList.contains();
,
Вот пример моей проблемы с кодом:
enum choices {a1, a2, b1, b2};
if(choices.???(a1)}{
//do this
}
Теперь я понимаю, что ArrayList
of Strings
будет лучшим маршрутом здесь, но мне нужно пропустить содержимое моего enum через switch/case в другом месте. Отсюда и моя проблема.
Если предположить, что чего-то подобного не существует, как я могу это сделать?
Ответы
Ответ 1
Это должно сделать это:
public static boolean contains(String test) {
for (Choice c : Choice.values()) {
if (c.name().equals(test)) {
return true;
}
}
return false;
}
Этот способ означает, что вам не придется беспокоиться о добавлении дополнительных значений перечисления позже, все они проверены.
Изменить: Если перечисление очень велико, вы можете вставлять значения в HashSet:
public static HashSet<String> getEnums() {
HashSet<String> values = new HashSet<String>();
for (Choice c : Choice.values()) {
values.add(c.name());
}
return values;
}
Тогда вы можете просто сделать: values.contains("your string")
, который возвращает true или false.
Ответ 2
Используйте Apache commons lang3 lib вместо
EnumUtils.isValidEnum(MyEnum.class, myValue)
Ответ 3
Вы можете использовать Enum.valueOf()
enum Choices{A1, A2, B1, B2};
public class MainClass {
public static void main(String args[]) {
Choices day;
try {
day = Choices.valueOf("A1");
//yes
} catch (IllegalArgumentException ex) {
//nope
}
}
Если вы ожидаете, что проверка будет часто терпеть неудачу, вам может быть лучше использовать простой цикл, как показали другие - если ваши перечисления содержат много значений, возможно, builda HashSet
или аналогичный из ваших перечислимых значений, преобразованных в строку, и запросите вместо этого HashSet
.
Ответ 4
Если вы используете Java 1.8, вы можете выбрать Stream + Lambda для реализации этого:
public enum Period {
DAILY, WEEKLY
};
//This is recommended
Arrays.stream(Period.values()).anyMatch((t) -> t.name().equals("DAILY1"));
//May throw java.lang.IllegalArgumentException
Arrays.stream(Period.values()).anyMatch(Period.valueOf("DAILY")::equals);
Ответ 5
Как, например, это:
enum MyData {
ONE,
TWO
}
@Test
public void test() {
if (!Enums.getIfPresent(MyData.class, "THREE").isPresent()) {
System.out.println("THREE is not here");
}
}
Ответ 6
Еще лучше:
enum choices {
a1, a2, b1, b2;
public static boolean contains(String s)
{
for(choices choice:values())
if (choice.name().equals(s))
return true;
return false;
}
};
Ответ 7
Вы можете сначала преобразовать перечисление в список, а затем использовать список содержит метод
enum Choices{A1, A2, B1, B2};
List choices = Arrays.asList(Choices.values());
//compare with enum value
if(choices.contains(Choices.A1)){
//do something
}
//compare with String value
if(choices.contains(Choices.valueOf("A1"))){
//do something
}
Ответ 8
Вы можете использовать этот
YourEnum {A1, A2, B1, B2}
boolean contains(String str){
return Sets.newHashSet(YourEnum.values()).contains(str);
}
Обновление, предлагаемое @wightwulf1944, включено, чтобы сделать решение более эффективным.
Ответ 9
Здесь было упомянуто несколько библиотек, но я скучаю по той, которую я действительно искал: Spring!
Существует ObjectUtils # содержитConstant, который по умолчанию не учитывает регистр, но может быть строгим, если хотите. Используется так:
if(ObjectUtils.containsConstant(Choices.values(), "SOME_CHOISE", true)){
// do stuff
}
Примечание. Я использовал перегруженный метод, чтобы продемонстрировать, как использовать проверку с учетом регистра. Вы можете опустить логическое значение, чтобы поведение не чувствительно к регистру.
Будьте осторожны с большими перечислениями, поскольку они не используют реализацию Map, как это делают некоторые...
В качестве бонуса он также предоставляет вариант valueOf: ObjectUtils # caseInsensitiveValueOf без учета регистра
Ответ 10
Несколько предположений:
1) Нет попытки/улова, так как это исключительный контроль потока
2) метод "содержит" должен быть быстрым, поскольку он обычно выполняется несколько раз.
3) Пространство не ограничено (обычное для обычных решений)
import java.util.HashSet;
import java.util.Set;
enum Choices {
a1, a2, b1, b2;
private static Set<String> _values = new HashSet<>();
// O(n) - runs once
static{
for (Choices choice : Choices.values()) {
_values.add(choice.name());
}
}
// O(1) - runs several times
public static boolean contains(String value){
return _values.contains(value);
}
}
Ответ 11
Я не думаю, что есть, но вы можете сделать что-то вроде этого:
enum choices {a1, a2, b1, b2};
public static boolean exists(choices choice) {
for(choice aChoice : choices.values()) {
if(aChoice == choice) {
return true;
}
}
return false;
}
Edit:
Посмотрите на версию Ричарда, так как это более подходит, так как это не сработает, если вы не конвертируете его в Strings, что делает Ричардс.
Ответ 12
Почему бы не комбинировать ответ Pablo с valueOf()?
public enum Choices
{
a1, a2, b1, b2;
public static boolean contains(String s) {
try {
Choices.valueOf(s);
return true;
} catch (Exception e) {
return false;
}
}
Ответ 13
Если вы используете Apache Commons (или хотите сделать это), вы можете проверить его с помощью:
ArrayUtils.contains(choices.values(), value)
Ответ 14
Этот работает для меня:
Arrays.asList(YourEnum.values()).toString().contains("valueToCheck");
Ответ 15
Этот подход можно использовать для проверки любого Enum
, вы можете добавить его в класс Utils
:
public static <T extends Enum<T>> boolean enumContains(Class<T> enumerator, String value)
{
for (T c : enumerator.getEnumConstants()) {
if (c.name().equals(value)) {
return true;
}
}
return false;
}
Используйте его следующим образом:
boolean isContained = Utils.enumContains(choices.class, "value");
Ответ 16
Я создал следующий класс для этой проверки
public class EnumUtils {
public static boolean isPresent(Enum enumArray[], String name) {
for (Enum element: enumArray ) {
if(element.toString().equals(name))
return true;
}
return false;
}
}
пример использования:
public ArrivalEnum findArrivalEnum(String name) {
if (!EnumUtils.isPresent(ArrivalEnum.values(), name))
throw new EnumConstantNotPresentException(ArrivalEnum.class,"Arrival value must be 'FROM_AIRPORT' or 'TO_AIRPORT' ");
return ArrivalEnum.valueOf(name);
}
Ответ 17
Вы можете использовать valueOf("a1")
, если хотите посмотреть на String
Ответ 18
Это перечисление, это постоянные значения, поэтому, если в выражении switch он просто делает что-то вроде этого:
case: val1
case: val2
Также почему вам нужно знать, что объявлено как константа?
Ответ 19
С guava это еще проще:
boolean isPartOfMyEnum(String myString){
return Lists.newArrayList(MyEnum.values().toString()).contains(myString);
}
Ответ 20
Это объединяет все подходы из предыдущих методов и должно иметь эквивалентную производительность. Он может использоваться для любого перечисления, встраивает решение "Изменить" из @Richard H и использует Исключения для недопустимых значений, таких как @bestsss. Единственный компромисс заключается в том, что класс должен быть указан, но это превращает его в двухстрочный.
import java.util.EnumSet;
public class HelloWorld {
static enum Choices {a1, a2, b1, b2}
public static <E extends Enum<E>> boolean contains(Class<E> _enumClass, String value) {
try {
return EnumSet.allOf(_enumClass).contains(Enum.valueOf(_enumClass, value));
} catch (Exception e) {
return false;
}
}
public static void main(String[] args) {
for (String value : new String[] {"a1", "a3", null}) {
System.out.println(contains(Choices.class, value));
}
}
}
Ответ 21
com.google.common.collect.Sets.newHashSet(MyEnum.values()).contains("myValue")
Ответ 22
чтобы проверить, присутствует ли значение, а также получить значение перечисления в обратном порядке:
protected TradeType getEnumType(String tradeType) {
if (tradeType != null) {
if (EnumUtils.isValidEnum(TradeType.class, tradeType)) {
return TradeType.valueOf(tradeType);
}
}
return null;
}
Ответ 23
Если вы используете Java 8 или выше, вы можете сделать это:
boolean isPresent(String testString){
return Stream.of(Choices.values()).map(Enum::name).collect(Collectors.toSet()).contains(testString);
}
Ответ 24
Set.of(CustomType.values())
.contains(customTypevalue)
Ответ 25
public boolean contains(Choices value) {
return EnumSet.allOf(Choices.class).contains(value);
}
Ответ 26
Моя репутация меньше, чем требуется, чтобы комментировать, но я думаю, что ответы chaiyachaiya и Pablo Santa Cruz полностью ошибочны.
Во-первых, Enum перезаписывает hashcode с помощью оператора ==
, так как экземпляры гарантированно являются одноточечными и поэтому не сравнивают логическое равенство операндов. Поэтому, если мы используем MyEnum.values()
и проверяем с помощью contains()
, мы всегда получаем false
.
Во-вторых, MyEnum.values().toString()
вызывает toString()
в объекте класса MyEnum
, а не в экземплярах класса MyEnum
(если вы переопределите этот метод в классе причин).
Итак, что вы получите с помощью Lists.newArrayList(MyEnum.values().toString()).contains(myString)
?
Ответ 27
enum
довольно мощные в Java. Вы легко можете добавить метод contains
к вашему перечислению (так как вы добавите метод в класс):
enum choices {
a1, a2, b1, b2;
public boolean contains(String s)
{
if (s.equals("a1") || s.equals("a2") || s.equals("b1") || s.equals("b2"))
return true;
return false;
}
};