Преобразование int в enum в Java

Я пишу полиномиальный калькулятор для задания курса и хочу использовать enum в случае переключения.

это метод перечисления, который я написал:

enum Options{
    ADDITION(1),
    MULTIPLICATION(2),
    EVALUATION(3),
    DERIVIATE(4),
    EXIT(5);

    public final int value;

     Options(int value){
         this.value = value;
     }

     public int getValue() {
         return value;
     }

     public static Options convert(int n) {
         for(Options o : values())
             if (o.getValue() == n)
                 return o;
         return null;
     }

}

этот переключатель case в программе:

choice = mysc.nextInt();
Options o = Options.convert(choice);
switch(o)
{
    case ADDITION: Add(isRational);break;
    case MULTIPLICATION: Mul(isRational);break;
    case EVALUATION: Evaluate(isRational);break;
    case DERIVIATE: Derivative(isRational);break;
    case EXIT: break;
}

Я хочу использовать enum в случае переключателя, но я хочу, чтобы ввод от пользователя был int, потому что это требование для назначения.

Я хочу преобразовать int, который я получаю от пользователя, в соответствующее перечисление и использовать его в случае переключения.

есть ли способ преобразовать его в правильное перечисление без использования метода convert внутри перечисления?

Почему бы вам не использовать метод convert. Я считаю, что этого можно избежать, но я не понимаю, зачем вам это нужно (это создает неприятные риски, связанные с ошибками, например, изменение перечислений меняет их индексы). То, что вы делаете с методом convert, выглядит разумным кроме вашего многострочного без скобок, если

Richard Tingle 15.04.2018 22:35

Мне кажется, что использование метода he convert по какой-то причине не является правильным, потому что ввод - это int, и я конвертирую его в enum. Так что такое ощущение: «Почему бы просто не использовать int в случае switch? Зачем преобразовывать в enum, а затем использовать switch?» Итак, я подумал, что есть лучший способ использовать enum, когда ввод int.

eyal mazuz 15.04.2018 22:41

Ах! Дело в том, что это могла быть программа гораздо большего размера. Пользовательский ввод всегда будет неаккуратным, но как только он будет преобразован в перечисления, его тип безопасен (компилятор не будет жаловаться, если вы передадите целое число 10456, но он не разрешит перечисление MuliZply. Таким образом, вы сделаете свой опасный как можно меньше части программы и как можно быстрее переходите к перечислениям. В крошечной игрушечной программе это, вероятно, не будет иметь особого смысла, но в любых более крупных программах это будет

Richard Tingle 15.04.2018 22:43
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
2 771
2

Ответы 2

Измените свой Enum, чтобы он начинался с индекса, основанного на 0, и используйте Enum.values()[index]. Вот простой пример кода, и вы, вероятно, захотите ввести какую-то проверку на недопустимые значения перечисления:

import java.io.BufferedInputStream;
import java.util.Scanner;

class Scratch {
    public static void main(String[] args) {
        Scanner input = new Scanner(new BufferedInputStream(System.in));
        System.out.println("Enter Value");
        int choice = Integer.parseInt(input.nextLine());
        System.out.println(choice);
        Options enumValue = Options.values()[choice];
        System.out.println(enumValue);
    }
}

enum Options{
    ADDITION(0),
    MULTIPLICATION(1),
    EVALUATION(2),
    DERIVIATE(3),
    EXIT(4);

    public final int value;

    Options(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

Выход

Кроме того, к вашему сведению, Enum.values()[index] может быть немного дорогим, так что имейте это в виду, если производительность является проблемой. Поскольку это для задания, я сомневаюсь, что это вызывает беспокойство, но о чем нужно помнить для вашего собственного понимания.

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

Richard Tingle 16.04.2018 12:28

@RichardTingle Я согласен с тем, что вы написали. Две причины, почему в этом конкретном случае, хотя я думаю, что это нормально. Решает вопрос OP как можно проще, и, во-вторых, если OP собирается использовать int в качестве значения, тогда OP в идеале будет начинаться с 0 для адресации значения int по умолчанию.

Always Learning 16.04.2018 22:12

Сопоставление целых чисел и значений перечисления на самом деле не является частью API, использующего значения перечисления. Прямо сейчас вы просите пользователя ввести целое число. Но что, если позже вы напишете графический интерфейс и представите имена значений перечисления в раскрывающемся списке? Или написать парсер для разбора арифметических выражений? Эти целые числа больше не будут иметь значения. Они существуют для меню, поэтому относятся к той части программы, которая отображает меню.

Вы можете представить Map<Integer,Options>, который будет сопоставлять вводимые пользователем данные со значениями перечисления. Но если вы добавили новое значение в перечисление, вам нужно будет не забыть добавить его и в свой Map.

Я бы использовал массив, возвращенный Options.values(). Обходите его, чтобы отобразить меню, и используйте его для поиска значений по индексу. К такому подходу также есть предостережения. Если вы измените порядок значений в своем коде, их порядок также изменится в массиве. Порядок пунктов меню изменится, что может сбить с толку пользователя. Но ваша программа все равно будет работать. Настоящая проблема с использованием порядковых значений перечисления заключается в том, что вы их сериализуете (записываете в постоянное хранилище, например в файл), а затем пытаетесь прочитать их после изменения порядка. Пока вы не сериализуете константы перечисления, можно использовать их порядковые значения.

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

Richard Tingle 16.04.2018 12:30

@RichardTingle Я хочу сказать, что эти значения изначально не принадлежат перечислению, потому что это связывает перечисление с пользовательским интерфейсом. Программа, отображающая меню, могла бы предоставить собственное отображение, но это было бы еще более хрупким. Использование порядкового номера гарантирует, что программа всегда будет работать и отображать все варианты. Единственным следствием изменения порядка значений перечисления будет их переназначение другим параметрам меню.

Kevin Krumwiede 17.04.2018 04:36

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