2012-03-25 16 views
21

Compiti: gioco Rock Paper Scissors.Qual è il modo corretto per confrontare una stringa con un valore enum?

Ho creato un'enumerazione:

 enum Gesture{ROCK,PAPER,SCISSORS}; 

da cui voglio mettere a confronto i valori per decidere chi vince - computer o umano. L'impostazione dei valori funziona bene e i confronti funzionano correttamente (la carta copre il rock, il rock schiaccia le forbici, le forbici taglia la carta). Tuttavia, non riesco a far funzionare la cravatta. L'utente è dichiarato vincitore ogni volta che c'è un pareggio.

Ahhh ... merda ... questo sarà chiarire: userPick è un String con valori rock, paper o scissors. Non riesco a utilizzare == per confrontare userPick a computerPick, che, come puoi vedere di seguito, viene lanciato come tipo Gesture dal mio 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.... 

sto indovinando che c'è un problema con rock non essere uguale a ROCK, oppure il String userPick non essere in grado di eguagliare Gesture computerPick perché quest'ultimo non è un String. Tuttavia, non sono in grado di trovare un esempio di una circostanza simile nel mio libro di testo o nei tutorial Java di Oracle, quindi non sono sicuro di come correggere il problema ...

Eventuali suggerimenti?

+3

Hai ragione, non si può paragonare la stringa "rock" al Gesture.ROCK enum. Avresti bisogno di una sorta di stringa -> Gestisci la funzione di mappatura in modo da poter confrontare due enumerazioni. Fortunatamente, Java ne fornisce già uno. Prova 'Gesture.valueOf ([your_string])'. Se ricordo correttamente, questa funzione è sensibile al maiuscolo/minuscolo. Ma potrei sbagliarmi. –

+0

Questa funzione fa distinzione tra maiuscole e minuscole. Grazie! –

risposta

24

Sto raccogliendo dalla tua domanda che userPick è un valore String. È possibile confrontare in questo modo:

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

Per inciso, se si ha la garanzia che computer è sempre uno dei valori 1, 2 o 3 (e nient'altro), è possibile convertirlo in un Gesture enum con:

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

+1 Clean e IMO, meglio della mia alternativa nel mio commento. –

+0

@Ted Hopp: bella, bella risposta. Grazie mille. Una domanda successiva, però ... che cosa fa il '.name' alla fine di' computerPick' ~ do ~? Presumo che questo sia qualcosa che punta a un'istanza specifica di 'computerPick'? Sto cercando di capire cosa questo lo differenzia da if (userPick.equalsIgnoreCase (computerPick())) '. Grazie! – dwwilson66

+0

@ dwwilson66 - Se 'computerPick' è un valore enum di tipo' Gesture', quindi 'computerPick(). Name()' restituisce un 'String' con il nome simbolico del valore corrente di' computerPick'. (Cioè, se 'computerPick == Gesture.ROCK', quindi' computerPick.name() 'sarà la stringa" ROCK ". (Ogni tipo' enum' ha metodi di istanza 'name()' e 'ordinal()' generato dal compilatore.Il tipo ha anche metodi statici 'values ​​()' e 'valueOf (String)' generati automaticamente.Vedi la [Specifica del linguaggio Java] (http://docs.oracle.com/javase/specs/jls/ se7/html/jls-8.html # jls-8.9). –

18

Si dovrebbe dichiarare toString() e valueOf() metodo 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

Questo è un ottimo esempio, in Java 7 il metodo valueOf è stato implementato in Enum. Funziona allo stesso modo del tuo esempio. – Evan

+7

Secondo la [Java Language Specification §8.9.2 ] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2), ogni dichiarazione di tipo 'enum' genera automaticamente un' valueOf (String) 'statico che si comporta come il tuo metodo (eccetto che genera un'eccezione invece di restituire' null' e fa distinzione tra maiuscole e minuscole). Ogni costante 'enum' eredita anche da' Enum' il metodo 'name()' che si comporta in modo simile al tuo 'toString()' (restituendo il nome esatto della costante 'enum'). @Evan - 'valueOf' è stato parte della classe' Enum' dal momento che le enumerazioni sono state introdotte in Java; non è nuovo per Java 7. –

+0

Questo è utile nei casi in cui l'enumerazione contiene un trattino basso e hai bisogno di un confronto .... sicuramente mi ha aiutato a ringraziarti .... – Grim

4

Puoi farlo in modo più semplice, come di seguito:

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

perché non 'return str.equals (enum.toString ()) 'e allora perché non usare semplicemente quell'espressione? – Dude

+0

Per un metodo che inizia con "è", è preferibile che restituisca booleano tutto il tempo. –

0

Questo sembra essere pulito.

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

E poi nel codice principale:

String airplane="BOEING_747"; 

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

Sembra che tu abbia fatto di tutto per sovraccaricare l'Enum semplicemente cambiando leggermente il comportamento. –

+0

@SalvadorValencia in realtà non sta sovraccaricando alcun oggetto ... –

-2

È possibile confrontare una stringa a un elemento enum come seguire,

public class principale {

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

Cercare di usare una stringa del genere in un confronto uguale probabilmente non funzionerà. Anche se lo fosse dovresti davvero impostarlo su una variabile. – KHeaney

+0

Niente di sbagliato nell'usare valori di stringa del genere, forse non è bello. E "google" .equals (...) non crea problemi. –

2

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

E se volete controllare Valore u scrivere:

SomeKindOfEnum.ENUM_NAME.equalValue("initialValue") 

sembra un pò bello per me :). Forse qualcuno lo troverà utile.

+0

sembra molto carino per me. –

1

Facendo un'importazione statica dei GestureTypes e quindi utilizzando il metodo valuesOf() potrebbe farlo sembrare molto Cleaner

enum GestureTypes{ROCK,PAPER,SCISSORS}; 

e

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

Definire enum:

public enum Gesture 
{ 
    ROCK, PAPER, SCISSORS; 
} 

definire un metodo per controllare enum contenuti:

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

    return false; 
} 

e 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; 
    } 
} 
Problemi correlati