Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use switch statement to compare a string against an enum

I'm making (my own version of)roulette with Java, and one of the types of bets a player can make is to choose the color that is going to be rolled. (Even is black, odd is red). Is there a way I can use a switch statement to compare a string against an enum?

private enum colors{red, black};
private String colorGuess;
private boolean colorVerify = false;
public void getColorGuess(){
do{
Scanner in = new Scanner(System.in);
colorGuess = in.nextLine();
switch(colors){
case red:
    colorVerify = true;
    break;
case black:
    colorVerify = true;
    break;
default:
    System.out.println("Invalid color selection!");
    break;
}while(colorVerify = false);

This is what i'm trying to get but it's not letting me use the enum 'colors' in a switch statement.

like image 235
gm95 Avatar asked Nov 07 '13 13:11

gm95


People also ask

How do you compare string and enum?

To compare a string with an enum, extend from the str class when declaring your enumeration class, e.g. class Color(str, Enum): . You will then be able to compare a string to an enum member using the equality operator == .

Can you use a switch statement around an enum?

An Enum keyword can be used with if statement, switch statement, iteration, etc. enum constants are public, static, and final by default. enum constants are accessed using dot syntax. An enum class can have attributes and methods, in addition to constants.

Can you toString an enum?

The Java Enum has two methods that retrieve that value of an enum constant, name() and . toString(). The toString() method calls the name() method which returns the string representation of the enum constant.

Can Switch compare strings?

The switch statement compares the String object in its expression with the expressions associated with each case label as if it were using the String. equals method; consequently, the comparison of String objects in switch statements is case sensitive.

Can you use == on enums?

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.


2 Answers

You must have an instance of an enum type (its member) on which you switch. You are trying to switch on the Enum class itself, which is a meaningless construct. So you probably need

colors col = colors.valueOf(colorGuess);
switch (col) ...

BTW the name should be Colors, not colors to respect the very important and non-optional Java naming convention.

like image 92
Marko Topolnik Avatar answered Nov 07 '22 20:11

Marko Topolnik


You can get an enum from a string with Enum.valueOf(). Take care here, the other answers fail to mention that Enum.valueOf() will throw an IllegalArgumentException if passed an string which isn't a valid member of the enum.

Be sure to properly format and indent your code, it helps us (and you!) read it and understand what's going on:

// note the capitalization, and the singular 'Color'
private enum Color {RED, BLACK}; 

// At least with the code provided, you don't need colorGuess or colorVerify to be
// instance variables, they can be local to the method.  Limiting the amount of
// time a variable lives for (its scope) is critical for quality, maintainable code

public Color getColorGuess() {
  Scanner in = new Scanner(System.in); // this should be outside the while loop
  while(in.hasNextLine()) {
    // .toUpperCase() lets you type "red" or "RED" and still match
    String line = in.nextLine().toUpperCase();
    try {
      // Enum.valueOf() throws an exception if the input is not valid
      Color guess = Color.valueOf(line);

      switch(guess) {
        case RED:
          return guess; // return, rather than break, to exit the method
        case BLACK:
          return guess;
        // As long as your switch statement covers all cases in your enum, you
        // don't need a default: case, you'll never reach it
      }
    } catch (IllegalArgumentException e) {
      System.out.println("Invalid color selection!");
    }
  }
}

Note that we now return guess in both cases, which is somewhat redundant. At least with the example code you provided, you don't actually need to track colorVerify at all, because the method will keep looping forever until a valid color is entered. You could replace the whole switch statement in my method with simply return guess; as you know it's a valid guess as soon as Color.valueOf() returns a value.

In other words, you could clean your code up to:

public static Color getColorGuess() {
  try (Scanner in = new Scanner(System.in)) {
    while(in.hasNextLine()) {
      try {
        return Color.valueOf(in.nextLine().toUpperCase());
      } catch (IllegalArgumentException e) {
        System.out.println("Invalid color selection!");
      }
    }
  }
}

Notice that the method is static now, and uses a try-with-resources block to close the Scanner once you're done with it.

like image 6
dimo414 Avatar answered Nov 07 '22 20:11

dimo414