web-dev-qa-db-ja.com

switchステートメントを使用して文字列を列挙型と比較します

私はJavaで(自分のバージョンの)ルーレットを作っています。プレイヤーができる賭けの種類の1つは、ロールされる色を選択することです。 (偶数は黒、奇数は赤)。 switchステートメントを使用して文字列を列挙型と比較する方法はありますか?

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

これは私が取得しようとしているものですが、switchステートメントで列挙型の「colors」を使用することはできません。

9
gm95

切り替える列挙型(そのmember)のインスタンスが必要です。意味のない構造であるEnumクラス自体をオンにしようとしています。だからあなたはおそらく必要です

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

ところで、非常に重要でオプションではないJava命名規則を尊重するために、名前はColorsではなくcolorsにする必要があります。

16
Marko Topolnik

Enum.valueOf() の文字列から列挙型を取得できます。ここで注意してください。他の回答では、列挙型の有効なメンバーではない文字列が渡された場合、Enum.valueOf()IllegalArgumentExceptionをスローすることに言及していません。

コードを適切にフォーマットしてインデントするようにしてください。コードを読んで、何が起こっているのかを理解するのに役立ちます。

_// 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!");
    }
  }
}
_

どちらの場合もguessを返すことに注意してください。これは、多少冗長です。少なくとも提供したサンプルコードでは、有効な色が入力されるまでメソッドが永久にループし続けるため、実際にはcolorVerifyを追跡する必要はまったくありません。 Color.valueOf()が値を返すとすぐに有効な推測であることがわかっているので、私のメソッドのswitchステートメント全体を単に_return guess;_に置き換えることができます。

つまり、コードを次のようにクリーンアップできます。

_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!");
      }
    }
  }
}
_

メソッドがstaticになり、完了したら try-with-resources ブロックを使用してScannerを閉じることに注意してください。

3
dimo414