Я пишу полиномиальный калькулятор для задания курса и хочу использовать 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 внутри перечисления?
Мне кажется, что использование метода he convert по какой-то причине не является правильным, потому что ввод - это int, и я конвертирую его в enum. Так что такое ощущение: «Почему бы просто не использовать int в случае switch? Зачем преобразовывать в enum, а затем использовать switch?» Итак, я подумал, что есть лучший способ использовать enum, когда ввод int.
Ах! Дело в том, что это могла быть программа гораздо большего размера. Пользовательский ввод всегда будет неаккуратным, но как только он будет преобразован в перечисления, его тип безопасен (компилятор не будет жаловаться, если вы передадите целое число 10456, но он не разрешит перечисление MuliZply. Таким образом, вы сделаете свой опасный как можно меньше части программы и как можно быстрее переходите к перечислениям. В крошечной игрушечной программе это, вероятно, не будет иметь особого смысла, но в любых более крупных программах это будет




Измените свой 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] может быть немного дорогим, так что имейте это в виду, если производительность является проблемой. Поскольку это для задания, я сомневаюсь, что это вызывает беспокойство, но о чем нужно помнить для вашего собственного понимания.
Стоит отметить, что на данный момент индекс, указанный в скобках в перечислении, не имеет ничего общего с тем, как все это работает, когда вы используете индекс заказа. Это отвечает на заданный вопрос, но я не думаю, что это хорошая идея (поскольку никто не ожидает, что переупорядочение перечислений сломает все)
@RichardTingle Я согласен с тем, что вы написали. Две причины, почему в этом конкретном случае, хотя я думаю, что это нормально. Решает вопрос OP как можно проще, и, во-вторых, если OP собирается использовать int в качестве значения, тогда OP в идеале будет начинаться с 0 для адресации значения int по умолчанию.
Сопоставление целых чисел и значений перечисления на самом деле не является частью API, использующего значения перечисления. Прямо сейчас вы просите пользователя ввести целое число. Но что, если позже вы напишете графический интерфейс и представите имена значений перечисления в раскрывающемся списке? Или написать парсер для разбора арифметических выражений? Эти целые числа больше не будут иметь значения. Они существуют для меню, поэтому относятся к той части программы, которая отображает меню.
Вы можете представить Map<Integer,Options>, который будет сопоставлять вводимые пользователем данные со значениями перечисления. Но если вы добавили новое значение в перечисление, вам нужно будет не забыть добавить его и в свой Map.
Я бы использовал массив, возвращенный Options.values(). Обходите его, чтобы отобразить меню, и используйте его для поиска значений по индексу. К такому подходу также есть предостережения. Если вы измените порядок значений в своем коде, их порядок также изменится в массиве. Порядок пунктов меню изменится, что может сбить с толку пользователя. Но ваша программа все равно будет работать. Настоящая проблема с использованием порядковых значений перечисления заключается в том, что вы их сериализуете (записываете в постоянное хранилище, например в файл), а затем пытаетесь прочитать их после изменения порядка. Пока вы не сериализуете константы перечисления, можно использовать их порядковые значения.
Я бы предложил использовать value в перечислении, введенном оператором, а не в порядковом номере, поскольку это не связывает ваш код с порядком перечисления. Дайте мне знать, если вы это сделаете, иначе это хороший ответ, за который я хотел бы проголосовать
@RichardTingle Я хочу сказать, что эти значения изначально не принадлежат перечислению, потому что это связывает перечисление с пользовательским интерфейсом. Программа, отображающая меню, могла бы предоставить собственное отображение, но это было бы еще более хрупким. Использование порядкового номера гарантирует, что программа всегда будет работать и отображать все варианты. Единственным следствием изменения порядка значений перечисления будет их переназначение другим параметрам меню.
Почему бы вам не использовать метод convert. Я считаю, что этого можно избежать, но я не понимаю, зачем вам это нужно (это создает неприятные риски, связанные с ошибками, например, изменение перечислений меняет их индексы). То, что вы делаете с методом convert, выглядит разумным кроме вашего многострочного без скобок, если