1

I'm writing a polynomial calculator for a course assignment and I want to use enum in the switch case.

this is the enum method I wrote:

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;
     }

}

this switch case in the program:

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;
}

I want to use enum in the switch case but I want the input from the user to be an int, because it's a requirement for the assignment.

I want to convert the int I get from the user to the corresponding enum and use it in the switch case.

is there a way to convert it to the correct enum without using the convert method inside the enum?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
eyal mazuz
  • 109
  • 1
  • 2
  • 10
  • 1
    Why don't you want to use the convert method. I believe it is possible to avoid it, but I don't see why you'd want to (it introduces nasty bug risks like reording the enums changes their indexes). What you're doing with the convert method looks sensible [other than your multiline braceless if](http://cafe.elharo.com/blogroll/braceless-if-considered-harmful/) – Richard Tingle Apr 15 '18 at 20:35
  • I feel like using he convert method isn't the correct way for some reason, because the input is an int and I'm converting it to enum. So it feels like: "why don't just use an int in the switch case in the first place? Why converting to enum and then use switch?" So I though there is a better way to use enum when the input is int. – eyal mazuz Apr 15 '18 at 20:41
  • Ah! The point is that this could be a much larger program. User input is always going to be squiffy, but as soon as its converted into enums its type safe (the compiler won't complain if you're passing around the integer 10456 but it will not allow the enum MuliZply. So you make your dangerous part of the program as small as possible and get into enums as quickly as you can. In a tiny toy program it probably won't make much sense but in any larger programs it will – Richard Tingle Apr 15 '18 at 20:43

2 Answers2

1

Change your Enum to start at a 0 based index and use Enum.values()[index]. Here is a simple example of the code and you'll probably want to introduce some sort of validation for invalid enum values:

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;
    }
}

Output

enter image description here

Also FYI, Enum.values()[index] can be a bit expensive so keep that in mind if performance is an issue. As this is for an assignment, I doubt that is a concern but something to keep in mind for your own understanding.

Always Learning
  • 2,623
  • 3
  • 20
  • 39
  • It's worth noting that at this point the index specified in brackets on the enum has nothing to do with how it all works as youre using the order index. This answers the question as asked but I don't think it's a good idea (as no one expects reordering enums to break everything) – Richard Tingle Apr 16 '18 at 10:28
  • @RichardTingle I agree with what you wrote. Two reasons though why in this particular case though I think it is ok. Solves OP's question as simply as possible and second, if OP is going to use int as the value than ideally OP would start at 0 to address default int value. – Always Learning Apr 16 '18 at 20:12
1

The mapping between integers and enum values is not really part of the API that uses the enum values. Right now, you're asking the user to input an integer. But what if you later write a GUI and present the names of the enum values in a drop down? Or write a parser to parse arithmetic expressions? Those integers will no longer be relevant. They exist for the menu, so they belong to the part of the program that displays the menu.

You could introduce a Map<Integer,Options> that would map user input to enum values. But if you added an new value to the enum, you'd have to remember to also add it to your Map.

I'd use the array returned by Options.values(). Iterate over it to display your menu, and use it to look up values by index. There are also caveats to this approach. If you rearrange the values in your code, their order will change in the array as well. The order of menu options would change, possibly confusing the user. But your program would still run. The real problem with using enum ordinal values is when you serialize them (write them to persistent storage, like a file) and then try to read them back after changing the order. As long as you're not serializing your enum constants, it's okay to use their ordinal values.

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
  • I'd suggest using the `value` on the enum that the op has introduced rather than the ordinal as that doesn't couple your code to enum ordering. Let me know if you do as this is otherwise a good answer that I'd like to upvote – Richard Tingle Apr 16 '18 at 10:30
  • @RichardTingle My point is that those values don't belong on the enum in the first place, because that couples the enum to the UI. The program that displays the menu could provide its own mapping, but that would be even more brittle. Using the ordinal ensures that the program will always run and display all the choices. The only consequence of changing the order of enum values would be their reassignment to different menu options. – Kevin Krumwiede Apr 17 '18 at 02:36