Switch case for two INT variables

前端 未结 6 1349
生来不讨喜
生来不讨喜 2021-01-12 19:07

Consider the following code :

if (xPoint > 0 && yPoint > 0) {
    m_navigations = Directions.SouthEast;
}
else if (xPoint > 0 && yP         


        
相关标签:
6条回答
  • 2021-01-12 19:24

    The simplest and easiest solution is to use multidimensional arrays.

    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
    }
    

    There are several advantages:

    • No if/else cascades which take some runtime and are hard to manage.
    • No creation of temporary Strings. In a tight game loop this may be important.
    • No linear search through lists or arrays.
    0 讨论(0)
  • 2021-01-12 19:25

    At the moment :

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

    Now I'll try what @danieln has suggested .

    0 讨论(0)
  • 2021-01-12 19:32

    You can do everything with enums. I created examples for the first two values, you can continue with the rest.

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

    So you can just call:

    m_navigations = Direction.getDirectionByPoints(xPoint,yPoint);
    
    0 讨论(0)
  • 2021-01-12 19:44

    Use signum to get -1, 0 or 1 on the direction like this:

    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 讨论(0)
  • 2021-01-12 19:46
    boolean xNeg  = xPoint  < 0;
    boolean yNeg  = yPoint  < 0;
    boolean xZero = xPoint == 0;
    boolean yZero = yPoint == 0;
    

    We have four bits, we have 2^4 possibilities, an array of Directions may do the rest...

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

    with directions a static final array of Directions initialized at class loading time.

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

    Indexing an array with an integer computed from ternaries, shift and or operators is less CPU consuming than a string concatenation used in a string switch and works well from Java 1.0.

    0 讨论(0)
  • 2021-01-12 19:49

    Similar to other answers but without strings. Just for fun :-)

    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;
    }
    
    0 讨论(0)
提交回复
热议问题