Java Enum, чтобы найти значения, дающие null

У меня есть следующий код: я хочу получить значение 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"));
    }
}

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

Arnaud 28.03.2019 10:52

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

Thomas 28.03.2019 10:58
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
2
1 679
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

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

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

Pra_A 28.03.2019 10:45

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

Murat Karagöz 28.03.2019 10:56

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

George Derpi 28.03.2019 11:19

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

Murat Karagöz 28.03.2019 11:26

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

George Derpi 28.03.2019 11:32

Ваш метод fromString() сравнивает свойство status значений перечисления с переданным параметром:

v.status.equalsIgnoreCase(text)

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

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

С ValueOf и v.name().equalsIgnoreCase(text) в обоих случаях я не получаю утвержденных значений. Это не работает

Pra_A 28.03.2019 10:51

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

Thomas 28.03.2019 10:52
Ответ принят как подходящий

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


You need to look for the имя field, not the положение дел field:
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");
    }
}

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

Existing enum: 'A'
Call 1: Approved
Call 2: Approved
Call 3 :
A: Approved
B: Approved

Non-existing enum: 'B'
Call 1: - Not found -
Call 2: - Not found -
Call 3 :
A: - Not found -
B:

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

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

Другие вопросы по теме