2012-03-25 13 views
21

Tarea: Rock Paper Scissors juego.¿Cuál es la forma correcta de comparar una Cadena con un valor enum?

He creado una enumeración:

 enum Gesture{ROCK,PAPER,SCISSORS}; 

de la que desea comparar los valores para decidir quién gana - ordenador o humano. Configuración de los valores funciona muy bien, y las comparaciones funciona correctamente (papel cubre la roca, roca aplasta tijeras, tijeras corta papel). Sin embargo, no puedo hacer que mi corbata funcione. El usuario es declarado ganador cuando hay un empate.

Ahhh ... mierda ... esto va a aclarar: userPick es una String con los valores rock, paper, o scissors. Soy incapaz de utilizar == comparar userPick a computerPick, que, como se puede ver a continuación, se convierte como tipo Gesture de mi 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.... 

que supongo que hay un problema con rock no ser igual a ROCK, o la String userPick no ser capaz de igualar Gesture computerPick ya que este último no es un String. Sin embargo, no puedo encontrar un ejemplo de una circunstancia similar en mi libro de texto o los Tutoriales de Java de Oracle, así que no estoy seguro de cómo corregir el problema ...

¿Alguna sugerencia?

+3

Tienes razón, no se puede comparar la cadena "roca" al Gesture.ROCK enumeración. Necesitarás una especie de cadena -> Función de mapeo de gestos para que puedas comparar dos enumeraciones. Afortunadamente, Java ya proporciona uno. Pruebe 'Gesture.valueOf ([your_string])'. Si recuerdo correctamente, esta función distingue entre mayúsculas y minúsculas. Pero podría estar equivocado. –

+0

Esa función distingue entre mayúsculas y minúsculas. ¡Gracias! –

Respuesta

24

estoy reuniendo por su pregunta que userPick es un valor String. Se puede comparar esta manera:

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

Como acotación al margen, si se le garantiza que computer es siempre uno de los valores 1, 2 o 3 (y nada más), puede convertirlo en una enumeración Gesture con:

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

+1 Clean, e IMO, mejor que mi alternativa en mi comentario. –

+0

@Ted Hopp: Encantadora y hermosa respuesta. Muchas gracias. Una pregunta de seguimiento, sin embargo ... ¿qué significa el '.name' al final de' computerPick' ~ do ~? Supongo que esto es algo que apunta a una instancia específica de 'computerPick'? Estoy tratando de entender qué hace esto que lo diferencia de 'if (userPick.equalsIgnoreCase (computerPick()))'. ¡Gracias! – dwwilson66

+0

@ dwwilson66 - Si 'computerPick' es un valor enum de tipo' Gesture', entonces 'computerPick(). Name()' devuelve 'String' con el nombre simbólico del valor actual de' computerPick'. (Es decir, si 'computerPick == Gesture.ROCK', entonces' computerPick.name() 'será la cadena" ROCK ". (Todos los tipos' enum' tienen métodos de instancia 'name()' y 'ordinal()' generado por el compilador. El tipo también tiene métodos estáticos 'values ​​()' y 'valueOf (String)' generados automáticamente. Consulte la [Especificación del lenguaje Java] (http://docs.oracle.com/javase/specs/jls/ se7/html/jls-8.html # jls-8.9). –

18

debe declarar toString() y valueOf() método en el 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

Este es un gran ejemplo, en Java 7, el método valueOf se ha implementado en Enum. Sin embargo, funciona igual que su ejemplo. – Evan

+7

De acuerdo con la [Especificación del lenguaje Java §8.9.2 ] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2), cada declaración de tipo 'enum' genera automáticamente un' valueOf (String) 'estático que se comporta como su método (excepto que arroja una excepción en lugar de devolver' null' y distingue entre mayúsculas y minúsculas). Cada constante 'enum' también hereda de 'Enum' el método' name() 'que se comporta de manera similar a su' toString() '(devolviendo el nombre exacto de la constante' enum'). @Evan - 'valueOf' ha sido parte de la clase' Enum' ya que las enumeraciones se introdujeron en Java; no es nuevo en Java 7. –

+0

Esto es útil para los casos en que las enumeraciones contienen un guión bajo y necesita una comparación ... definitivamente me ayudó a agradecerle ... – Grim

4

Puede hacerlo de una manera más simple, como el siguiente:

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

¿por qué no 'return str.equals (enum.toString ()) 'y luego ¿por qué no simplemente usar esa expresión? – Dude

+0

Para un método que comienza con 'es', se prefiere que devuelva boolean todo el tiempo. –

0

Esto parece estar limpio.

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

Y luego en código principal:

String airplane="BOEING_747"; 

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

Me parece que hiciste todo lo posible para sobrecargar el Enum y cambiar el comportamiento un poco. –

+0

@SalvadorValencia no realmente sobrecargando ningún objeto ... –

-2

Puede comparar una cadena a un elemento de enumeración que sigue,

public class Principal {

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

Intentar usar una cadena como esa en una comparación de iguales probablemente no funcionará. Incluso si lo hace, realmente debería establecerlo en una variable. – KHeaney

+0

No hay nada malo con el uso de valores de cadena así, tal vez no es bonito. Y "google" .equals (...) no compila ningún problema. –

2

Mi idea:

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

Y si quieres comprobar Valor u escribir:

SomeKindOfEnum.ENUM_NAME.equalValue("initialValue") 

Un poco se ve bien para mí :). Quizás alguien lo encuentre útil.

+0

me parece muy agradable. –

1

Hacer una importación estática de los GestureTypes y luego utilizando el método valuesOf() podría hacer que se vea mucho más limpia

enum GestureTypes{ROCK,PAPER,SCISSORS}; 

y

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

Definir enumeración:

public enum Gesture 
{ 
    ROCK, PAPER, SCISSORS; 
} 

definir un método para comprobar enum contenido:

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

    return false; 
} 

y usarlo:

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