2013-04-13 13 views
5

Rozważmy następujący kod:przypadek Przełącznik do dwóch zmiennych 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; 
} 

Jest to dość brzydkie, i chcę użyć przełącznika przypadek, ale w jaki sposób mogę korzystać z 2switch zmiennych?

myślałem o czymś takim this - odpowiedź z @Frits van Campen, ale muszę użyć > i < przewoźników ...

Dzięki

Odpowiedz

6

można zrobić wszystko z teksty stałe. Stworzyłem przykłady dla pierwszych dwóch wartości, możesz kontynuować z resztą.

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

więc można po prostu zadzwonić:

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

+1: Doskonałe wykorzystanie wymówek – Aubin

+0

@danieln: Wygląda świetnie! – ron

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

Mamy cztery bity, mamy 2^4 możliwości, szereg kierunków mogą zrobić resztę ...

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

z directions się static final Tablica wskazówek zainicjowana w czasie ładowania klasy.

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 
    ... 
} 

Indeksowanie tablicę liczbę całkowitą wyliczony z ternaries, zmiany i lub operatorów mniej czasochłonne niż procesor konkatenacji strumienia we przełącznika łańcucha i działa dobrze z Java 1.0.

2

Zastosowanie signum dostać -1, 0 lub 1 w kierunku takiego:

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

Pamiętaj, że użycie 'String's w instrukcji' case' jest dostępne tylko po Java 1.7+ – Chan

+0

Wiem, że odpowiedź od Fritsa van Campena, do której odnosi się @ron, również używa ciągów w przełączniku, więc zakładam, że Ron to wie. – bluevoid

+0

@bluevoid: Nice! – ron

0

Obecnie:

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

Teraz postaram co @danieln zasugerował.

1

Podobny do innych odpowiedzi, ale bez ciągów. Dla zabawy :-)

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

Najprostszym i najłatwiejszym rozwiązaniem jest użycie tablic wielowymiarowych.

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 
} 

Istnieje kilka zalet:

  • Nie if/else kaskady który zajmie trochę czasu pracy i są trudne do opanowania.
  • Brak tworzenia tymczasowych ciągów znaków. W ciasnej pętli gry może to być ważne.
  • Bez liniowego przeszukiwania list lub tablic.