Java Enum для поиска значений, дающих null

#java #enums

#java #перечисления

Вопрос:

У меня есть следующий код: я хочу получить значение Approved при передаче A , и если я прошел R , то я должен получить Reject New , но он не работает и выдает мне нулевое значение.

 public enum MyEnum {
    A("Approved"),
    R("Reject New"),

    private String status;

    private MyEnum(String status) {
        this.status = status;
    }

    public String getStatus() {
        return status;
    }

    public static MyEnum fromString(String text) {
        return Arrays.stream(values())
          .filter(v -> v.status.equalsIgnoreCase(text))
          .findFirst()
          .orElse(null);
    }
}
  

Другой код:

 public class Demo {
    public static void main(String[] args) {
        System.out.println(MyEnum.fromString("A"));
    }
}
  

Комментарии:

1. Затем используйте v.name().equalsIgnoreCase(text) . Также обратите внимание, что MyEnum.valueOf("A") это также вернет ожидаемое значение enum, но чувствительно к регистру.

2. «Я хочу получить утвержденное значение при передаче …» — это не подходит, MyEnum fromString(String text) потому что вы возвращаете экземпляр MyEnum , который имеет значения A и R. «Approved» — это String свойство этих значений, поэтому, если вы хотите, чтобы ваш метод преобразовал «A» в «Approved», возвращаемое значение также должно быть String .

Ответ №1:

Вы сравниваете неправильную строку. Это должно быть

  System.out.println(MyEnum.fromString("Approved"));
  

Чтобы получить перечисление, вы можете использовать valueOf

 System.out.println(MyEnum.valueOf("A").getStatus()); // prints Approved
  

Комментарии:

1. Я хочу передать A и получить утвержденное значение. Я хочу наоборот

2. @PAA Смотрите вторую версию

3. Не используйте valueOf() подобным образом. Если вы передадите несуществующее значение, значение в неправильном регистре или значение с дополнительным пробелом, это приведет к ошибкам.

4. @GeorgeDerpi Он уже ожидает null значение от своего fromString метода. Итак, я не вижу здесь проблем, поскольку null это допустимый возврат.

5. Первый код подразумевает, что он ищет перечисление на основе статуса, но это наоборот. Второй код с valueOf() приведет к сбою во всех случаях, которые я упомянул в моем предыдущем комментарии.

Ответ №2:

Не используйте valueOf() напрямую. Это чувствительно к регистру и выдает ошибку, когда не находит соответствующее enum .


Вам нужно искать поле name, а не поле status:

 public static MyEnum fromString(String text) {
        return Arrays.stream(values())
          .filter(v -> v.name().equalsIgnoreCase(text))
          .findFirst()
          .orElse(null);
    }
}
  

И как только у вас будет ваше перечисление, вызовите getStatus() метод для возврата Approved :

     MyEnum foundEnum = MyEnum.fromString("A");
    System.out.println(foundEnum != null ? foundEnum.getStatus() : "- Not found -");
  

Или используйте Optional подход:

 public static Optional<MyEnum> fromStringOptional(String text) {
    try {
        return Optional.of(MyEnum.valueOf(text));
    } catch (IllegalArgumentException|NullPointerException e) {
        return Optional.empty();
    }
}
  

И выполните

 Optional<MyEnum> foundEnum3 = MyEnum.fromStringOptional(searchString);
System.out.println(foundEnum3.map(a -> a.getStatus()).orElse("- Not found -"));
System.out.println(foundEnum3.isPresent() ? foundEnum3.getStatus() : "- Not found -");
  

Полный пример:

 import java.util.Arrays;
import java.util.Optional;

public class EnumDemo {

    public enum MyEnum {
        A("Approved"),
        R("Reject New");

        private String status;

        private MyEnum(String status) {
            this.status = status;
        }

        public String getStatus() {
            return status;
        }

        public static MyEnum getEnumfromString(String text) {
            return Arrays.stream(values())
              .filter(v -> v.name().equalsIgnoreCase(text))
              .findFirst()
              .orElse(null);
        }

        public static String getStatusfromString(String text) {
            MyEnum found = Arrays.stream(values())
                  .filter(v -> v.name().equalsIgnoreCase(text))
                  .findFirst()
                  .orElse(null);
            return found != null ? found.getStatus() : "- Not found -";
        }

        public static Optional<MyEnum> getOptionalfromString(String text) {
            try {
                return Optional.of(MyEnum.valueOf(text));
            } catch (IllegalArgumentException|NullPointerException e) {
                return Optional.empty();
            }
        }
    }

    public static void doCalls(String searchString) {
        System.out.print("Call 1: ");
        MyEnum foundEnum = MyEnum.getEnumfromString(searchString);
        System.out.println(foundEnum != null ? foundEnum.getStatus() : "- Not found -");

        System.out.print("Call 2: ");
        System.out.println(MyEnum.getStatusfromString(searchString));

        System.out.println("Call 3 :");
        System.out.print(" A: ");
        Optional<MyEnum> foundOptional = MyEnum.getOptionalfromString(searchString);
        System.out.println(foundOptional.map(a -> a.getStatus()).orElse("- Not found -"));
        //or this, which only prints if the enum was found
        System.out.print(" B: ");
        foundOptional.ifPresent(a -> System.out.println(a.getStatus()));
    }

    public static void main(String[] args) {
        System.out.println("Existing enum: 'A'");
        doCalls("A");
        System.out.println("");
        System.out.println("Non-existing enum: 'B'");
        doCalls("B");
    }
}
  

Тестовый вывод:

Существующее перечисление: ‘A’
Вызов 1: Утвержден
Вызов 2: Утвержден
Вызов 3:
A: Утвержден
B: Утвержден

Несуществующий enum: ‘B’
Вызов 1: — Не найден —
Вызов 2: — Не найден —
Вызов 3:
A: — Не найден —
B:

Ответ №3:

Ваш fromString() метод сравнивает status свойство enum values с переданным параметром:

 v.status.equalsIgnoreCase(text)
  

Таким образом, когда вы передаете "A" as text , это будет сравниваться с "Approved" и "Reject New" , и ни одно из них не будет соответствовать.

Если вы хотите получить перечисление для, "A" которое, по-видимому, является именем значения, используйте MyEnum.valueOf("A") .

Комментарии:

1. С помощью valueOf и v.name ().equalsIgnoreCase(текст), в обоих случаях я не получаю утвержденных значений. Это не работает

2. @PAA возможно, вы захотите поделиться своим кодом с. Обратите внимание, что "Approved" это свойство перечисления, а не его имя. Если вы хотите получить эту строку, используйте MyEnum.valueOf("A").getStatus() — конечно, вам также придется обрабатывать регистр null.

Ответ №4:

простой способ сделать это, а также вы можете сделать его универсальным, но не рекомендуется

 public static MyEnum fromString(String text) {
        try {
            return Enum.valueOf(MyEnum.class, text.toUpperCase());
        } catch (Exception e) {
        }
        return null;
    }
  

вызывающий метод

 System.out.println(MyEnum.fromString("A"));
  

вывод :

 A