2012-03-25 3 views
21

Домашнее задание: Rock Paper Scissors.Каков правильный способ сравнения строки со значением перечисления?

Я создал перечисление:

 enum Gesture{ROCK,PAPER,SCISSORS}; 

, из которого я хочу, чтобы сравнить значения, чтобы решить, кто победит - компьютер или человек. Настройка значений работает очень хорошо, и сравнения работают правильно (бумажные обложки скалы, скальные породы, ножницы, ножницы разрезают бумагу). Однако я не могу заставить свою галстук работать. Пользователь объявляется победителем в любое время, когда есть связь.

Ааа ... дерьмо ... это будет разъяснено: userPick является String со значениями rock, paper или scissors. Я не могу использовать ==, чтобы сравнить userPick с computerPick, который, как вы можете видеть ниже, отличен как тип Gesture из моего enum.

 if(computer == 1) 
     computerPick = Gesture.ROCK; 
     else 
     if(computer == 2) 
      computerPick = Gesture.PAPER; 
     else 
      computerPick = Gesture.SCISSORS; 
     if(userPick.equals(computerPick)) 
     { 
      msg = "tie"; 
      ++tieGames; 
     } 
      etc.... 

Я предполагаю, что есть проблема с rock не равна ROCK или String userPick не в состоянии соответствовать Gesture computerPick, поскольку последний не является String. Тем не менее, я не могу найти пример аналогичного обстоятельства в своем учебнике или учебниках Java по Java, поэтому я не уверен, как исправить проблему ...

Любые подсказки?

+3

Вы правы, вы не можете сравнить строку «рок» в перечислениях Gesture.ROCK. Вам понадобится какая-то строка -> Функция сопоставления жестов, чтобы вы могли сравнить две перечисления. К счастью, Java уже предоставляет один. Попробуйте 'Gesture.valueOf ([your_string])'. Если я правильно помню, эта функция чувствительна к регистру. Но я могу ошибаться. –

+0

Эта функция чувствительна к регистру. Благодаря! –

ответ

24

Я собираюсь с вашего вопроса, что userPick является величиной String. Вы можете сравнить это следующим образом:

if (userPick.equalsIgnoreCase(computerPick.name())) . . . 

Как и в стороне, если вы гарантированы что computer всегда одна из значений 1, 2 или 3 (и ничего больше), вы можете преобразовать его в Gesture перечисления с:

Gesture computerPick = Gesture.values()[computer - 1]; 
+0

+1 Чистота, и ИМО, лучше, чем моя альтернатива в моем комментарии. –

+0

@Ted Hopp: Прекрасный, прекрасный ответ. Спасибо. Один последующий вопрос, хотя ... что делает '.name' в конце' computerPick' ~ do ~? Я предполагаю, что это то, что указывает на конкретный экземпляр 'computerPick'? Я пытаюсь понять, что это отличает его от 'if (userPick.equalsIgnoreCase (computerPick())). благодаря! – dwwilson66

+0

@ dwwilson66 - Если 'computerPick' является значением перечисления типа' Gesture', то 'computerPick(). Name()' возвращает 'String' с символическим именем текущего значения' computerPick'. (То есть, если 'computerPick == Gesture.ROCK', то' computerPick.name() 'будет строкой« ROCK ». (Каждый тип« enum »имеет методы экземпляра' name() 'и' ordinal() ' созданный компилятором.Тип также имеет статические методы 'values ​​()' и 'valueOf (String)' автоматически сгенерированы. См. [Спецификация языка Java] (http://docs.oracle.com/javase/specs/jls/ se7/html/jls-8.html # jls-8.9) –

18

Вы должны объявить toString() и valueOf() метод в enum.

import java.io.Serializable; 

public enum Gesture implements Serializable { 
    ROCK,PAPER,SCISSORS; 

    public String toString(){ 
     switch(this){ 
     case ROCK : 
      return "Rock"; 
     case PAPER : 
      return "Paper"; 
     case SCISSORS : 
      return "Scissors"; 
     } 
     return null; 
    } 

    public static Gesture valueOf(Class<Gesture> enumType, String value){ 
     if(value.equalsIgnoreCase(ROCK.toString())) 
      return Gesture.ROCK; 
     else if(value.equalsIgnoreCase(PAPER.toString())) 
      return Gesture.PAPER; 
     else if(value.equalsIgnoreCase(SCISSORS.toString())) 
      return Gesture.SCISSORS; 
     else 
      return null; 
    } 
} 
+1

Это отличный пример, в Java 7 метод valueOf был реализован в Enum. Он работает так же, как ваш пример. – Evan

+7

Согласно [Спецификация Java Language §8.9.2 ] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2), каждое объявление типа «enum» автоматически генерирует статическую «valueOf (String)», которая ведет себя подобно вашему методу (кроме того, что она выдает исключение вместо возврата «null» и чувствительна к регистру). Каждая константа 'enum' также наследует от' Enum' метод 'name()', который ведет себя аналогично вашему 'toString()' (возвращающему точное имя константы 'enum'). @Evan - 'valueOf' был частью класса Enum, поскольку перечисления были введены в Java; это не ново для Java 7. –

+0

Это полезно для случаев, когда перечисления содержат подчеркивание, и вам нужно сравнение .... определенно помогло мне поблагодарить вас .... – Grim

4

Вы можете сделать это более простым способом, как ниже:

boolean IsEqualStringandEnum (String str,Enum enum) 
{ 
    if (str.equals(enum.toString())) 
    return true; 
    else 
    return false; 
} 
+3

почему бы не 'return str.equals (enum.toString ()) ', а затем почему бы просто не использовать это выражение? – Dude

+0

Для метода, начинающегося с 'is', предпочтительно, чтобы он возвращал значение boolean все время. –

0

Это кажется чистой.

public enum Plane{ 

/** 
* BOEING_747 plane. 
*/ 
BOEING_747("BOEING_747"), 

/** 
* AIRBUS_A380 Plane. 
*/ 
AIRBUS_A380("AIRBUS_A380"), 

; 

private final String plane;  

private Plane(final String plane) { 
    this.plane= plane; 
} 

Plane(){ 
    plane=null; 
} 


/** 
* toString method. 
* 
* @return Value of this Enum as String. 
*/ 
@Override 
public String toString(){ 
    return plane; 
} 

/** 
* This method add support to compare Strings with the equalsIgnoreCase String method. 
* 
* Replicated functionality of the equalsIgnorecase of the java.lang.String.class 
* 
* @param value String to test. 
* @return True if equal otherwise false. 
*/ 
public boolean equalsIgnoreCase(final String value){ 
    return plane.equalsIgnoreCase(value); 
} 

И тогда в основном коде:

String airplane="BOEING_747"; 

if(Plane.BOEING_747.equalsIgnoreCase(airplane)){ 
    //code 
} 
+0

Кажется, вы пошли на многое, чтобы перегрузить Enum, чтобы немного изменить поведение. –

+0

@SalvadorValencia действительно не перегружает какой-либо объект ... –

-2

Вы можете сравнить строку с элементом перечисления, как следовать,

общественного класса Main {

enum IaaSProvider{ 
    aws, 
    microsoft, 
    google 
} 

public static void main(String[] args){ 

    IaaSProvider iaaSProvider = IaaSProvider.google; 

    if("google".equals(iaaSProvider.toString())){ 
     System.out.println("The provider is google"); 
    } 

} 

}

+0

Попытка использовать строку, подобную той, которая сравнивается со сравнением, скорее всего, не сработает. Даже если это так, вы должны действительно установить его в переменную. – KHeaney

+0

Ничего плохого в использовании таких значений строк, может быть, не очень. И «google» .equals (...) не создает проблем. –

2

Моя мысль:

public enum SomeKindOfEnum{ 
    ENUM_NAME("initialValue"); 

    private String value; 

    SomeKindOfEnum(String value){ 
     this.value = value; 
    } 

    public boolean equalValue(String passedValue){ 
     return this.value.equals(passedValue); 
    } 
} 

А если и хотят, чтобы проверить значение и написать:

SomeKindOfEnum.ENUM_NAME.equalValue("initialValue") 

Любопытное выглядит хорошо для меня :). Может быть, кто-то найдет это полезным.

+0

Мне очень приятно. –

1

Ведение статического импорта GestureTypes, а затем с помощью метода valuesOf() может сделать его много cleaner-

enum GestureTypes{ROCK,PAPER,SCISSORS}; 

и

import static com.example.GestureTypes.*; 
public class GestureFactory { 

public static Gesture getInstance(final String gesture) { 
    if (ROCK == valueOf(gesture)) 
     //do somthing 
    if (PAPER == valueOf(gesture)) 
     //do somthing 
} 

}

1

Определение перечисления:

public enum Gesture 
{ 
    ROCK, PAPER, SCISSORS; 
} 

Определить метод для проверки enum содержания:

private boolean enumContainsValue(String value) 
{ 
    for (Gesture gesture : Gesture.values()) 
    { 
     if (gesture.name().equals(value)) 
     { 
      return true; 
     } 
    } 

    return false; 
} 

И использовать его:

String gestureString = "PAPER"; 

if (enumContainsValue(gestureString)) 
{ 
    Gesture gestureId = Gesture.valueOf("PAPER"); 

    switch (gestureId) 
    { 
     case ROCK: 
      Log.i("TAG", "ROCK"); 
      break; 

     case PAPER: 
      Log.i("TAG", "PAPER"); 
      break; 

     case SCISSORS: 
      Log.i("TAG", "SCISSORS"); 
      break; 
    } 
} 
Смежные вопросы