2013-04-13 13 views
5

Si consideri il seguente codice:caso Interruttore per due variabili INT

if (xPoint > 0 && yPoint > 0) { 
    m_navigations = Directions.SouthEast; 
} 
else if (xPoint > 0 && yPoint < 0) { 
    m_navigations = Directions.NorthEast; 
} 
else if (xPoint < 0 && yPoint > 0) { 
    m_navigations = Directions.SouthWest; 
} 
else if (xPoint < 0 && yPoint < 0) { 
    m_navigations = Directions.NorthWest; 
} 
else if (xPoint == 0 && yPoint < 0) { 
    m_navigations = Directions.North; 
} 
else if (xPoint == 0 && yPoint > 0) { 
    m_navigations = Directions.South; 
} 
else if (xPoint > 0 && yPoint == 0) { 
    m_navigations = Directions.East; 
} 
else if (xPoint < 0 && yPoint == 0) { 
    m_navigations = Directions.West; 
} 

Questo è abbastanza brutto, e voglio usare caso interruttore, ma come posso usare switch con 2 variabili?

ho pensato a qualcosa di simile this - la risposta di @Frits van Campen, ma ho bisogno di usare > e < operatori ...

Grazie

risposta

6

si può fare tutto con le enumerazioni. Ho creato degli esempi per i primi due valori, puoi continuare con il resto.

public enum Direction 
{ 
    SouthEast(1,1), 
    NorthEast(1,-1); 

    int _xPoint, _yPoint; 

    Direction(int xPoint, int yPoint) 
    { 
     _xPoint = xPoint; 
     _yPoint = yPoint; 
    } 

    public static Direction getDirectionByPoints(int xPoint, int yPoint) 
    { 
     for (Direction direction : Direction.values()) 
     { 
      if( Integer.signum(xPoint) == direction._xPoint 
       && Integer.signum(yPoint) == direction._yPoint) 
      { 
       return direction; 
      } 
     } 
     throw new IllegalStateException("No suitable Direction found"); 
    } 
} 

Così si può chiamare:

m_navigations = Direction.getDirectionByPoints(xPoint,yPoint); 
+0

+1: uso eccellente delle enumerazioni – Aubin

+0

@danieln: sembra fantastico! – ron

0
boolean xNeg = xPoint < 0; 
boolean yNeg = yPoint < 0; 
boolean xZero = xPoint == 0; 
boolean yZero = yPoint == 0; 

Abbiamo quattro punte, abbiamo 2^4 possibilità, una serie di indicazioni può fare il resto ...

int index = 
    ((xNeg ?1:0)<<3)| 
    ((yNeg ?1:0)<<2)| 
    ((xZero?1:0)<<1)| 
    ((yZero?1:0)<<0); 
Directions dir = directions[index]; 

con directions un static final array di istruzioni inizializzate in fase di caricamento della classe.

static final Directions[] directions = { 
    Direction.NorthEast, // false, false, false, false ==> x > 0 && y > 0 
    Direction.East,  // false, false, false, true ==> x > 0 && y == 0 
    Direction.North,  // false, false, true , false ==> x == 0 && y > 0 
    ... 
} 

indicizzazione una matrice con un numero intero calcolata da ternari, spostamento e operatori o è meno CPU consumo di una concatenazione stringa utilizzata in uno switch stringa e funziona bene da Java 1.0.

2

Usa signum per ottenere -1, 0 o 1 sulla direzione in questo modo:

String direction = Integer.signum(xPoint)+","+Integer.signum(yPoint); 
switch(direction){ 
    case "1,1": 
    m_navigations = Directions.SouthEast; 
    break; 
    case "-1,0" 
    m_navigations = Directions.West; 
    break; 

etc.. 
} 
+0

Attenzione che utilizzando '' String's in dichiarazione case' è disponibile solo dopo Java 1.7+ – Chan

+0

Lo so, la risposta da Frits van Campen che @ron si riferisce a usi stringhe nel aswell interruttore, quindi immagino che Ron lo sa. – bluevoid

+0

@bluevoid: Bello! – ron

0

Al momento:

String direction = Integer.signum(xPoint) + "|" + Integer.signum(yPoint); 
    switch(direction) 
    { 
     case "1|1": 
      {m_navigations = Directions.SouthEast; break;} 
     case "1|-1": 
      {m_navigations = Directions.NorthEast; break;} 
     case "-1|1": 
      {m_navigations = Directions.SouthWest; break;} 
     case "-1|-1": 
      {m_navigations = Directions.NorthWest; break;} 
     case "0|-1": 
      {m_navigations = Directions.North; break;} 
     case "0|1": 
      {m_navigations = Directions.South; break;} 
     case "1|0": 
      {m_navigations = Directions.East; break;} 
     case "-1|0": 
      {m_navigations = Directions.West; break;} 
     default: break;   
    } 

Ora cercherò quello @danieln ha suggerito.

1

Simile ad altre risposte ma senza stringhe. Solo per divertimento :-)

public Directions getDirection(int xPoint, int yPoint) { 
    int num = 8 * (xPoint == 0 ? 0 : xPoint > 0 ? 1 : 2); 
    num += yPoint == 0 ? 0 : yPoint > 0 ? 1 : 2; 
    switch (num) { 
    case 01: 
     return Directions.South; 
    case 02: 
     return Directions.North; 
    case 010: 
     return Directions.East; 
    case 011: 
     return Directions.SouthEast; 
    case 012: 
     return Directions.NorthEast; 
    case 020: 
     return Directions.West; 
    case 021: 
     return Directions.SouthWest; 
    case 022: 
     return Directions.NorthWest; 
    } 
    return Directions.None; 
} 
2

La soluzione più semplice e semplice consiste nell'utilizzare array multidimensionali.

public class CalculateDirections { 
    private final static Directions DIRECTION_MAP[][] = { 
     {Directions.NorthWest, Directions.North, Directions.NorthEast}, 
     {Directions.West, null, Directions.East}, 
     {Directions.SouthWest, Directions.South, Directions.SouthEast}, 
    }; 

    public static void main(String[] args) { 
     int x = Integer.valueOf(args[0]); 
     int y = Integer.valueOf(args[1]); 

     int signumX = Integer.signum(x); 
     int signumY = Integer.signum(y); 
     Directions direction = DIRECTION_MAP[signumY + 1][signumX + 1]; 

     System.out.println(direction); 
    } 
} 

enum Directions { 
    SouthEast, NorthEast, SouthWest, NorthWest, North, South, East, West 
} 

Ci sono diversi vantaggi:

  • No se/cascate altro che prendono un po 'di runtime e sono difficili da gestire.
  • Nessuna creazione di stringhe temporanee. In un ciclo di gioco stretto questo può essere importante.
  • Nessuna ricerca lineare attraverso elenchi o array.