Java Enum Methods - return opposite direction enum

后端 未结 6 722
时光说笑
时光说笑 2020-11-27 10:34

I would like to declare an enum Direction, that has a method that returns the opposite direction (the following is not syntactically correct, i.e, enums cannot be instantiat

相关标签:
6条回答
  • 2020-11-27 10:50

    This works:

    public enum Direction {
        NORTH, SOUTH, EAST, WEST;
    
        public Direction oppose() {
            switch(this) {
                case NORTH: return SOUTH;
                case SOUTH: return NORTH;
                case EAST:  return WEST;
                case WEST:  return EAST;
            }
            throw new RuntimeException("Case not implemented");
        }
    }
    
    0 讨论(0)
  • 2020-11-27 10:55

    For those lured here by title: yes, you can define your own methods in your enum. If you are wondering how to invoke such non-static method, you do it same way as with any other non-static method - you invoke it on instance of type which defines or inherits that method. In case of enums such instances are simply ENUM_CONSTANTs.

    So all you need is EnumType.ENUM_CONSTANT.methodName(arguments).


    Now lets go back to problem from question. One of solutions could be

    public enum Direction {
    
        NORTH, SOUTH, EAST, WEST;
    
        private Direction opposite;
    
        static {
            NORTH.opposite = SOUTH;
            SOUTH.opposite = NORTH;
            EAST.opposite = WEST;
            WEST.opposite = EAST;
        }
    
        public Direction getOppositeDirection() {
            return opposite;
        }
    
    }
    

    Now Direction.NORTH.getOppositeDirection() will return Direction.SOUTH.


    Here is little more "hacky" way to illustrate @jedwards comment but it doesn't feel as flexible as first approach since adding more fields or changing their order will break our code.

    public enum Direction {
        NORTH, EAST, SOUTH, WEST;
    
        // cached values to avoid recreating such array each time method is called
        private static final Direction[] VALUES = values();
    
        public Direction getOppositeDirection() {
            return VALUES[(ordinal() + 2) % 4]; 
        }
    }
    
    0 讨论(0)
  • 2020-11-27 10:57

    Create an abstract method, and have each of your enumeration values override it. Since you know the opposite while you're creating it, there's no need to dynamically generate or create it.

    It doesn't read nicely though; perhaps a switch would be more manageable?

    public enum Direction {
        NORTH(1) {
            @Override
            public Direction getOppositeDirection() {
                return Direction.SOUTH;
            }
        },
        SOUTH(-1) {
            @Override
            public Direction getOppositeDirection() {
                return Direction.NORTH;
            }
        },
        EAST(-2) {
            @Override
            public Direction getOppositeDirection() {
                return Direction.WEST;
            }
        },
        WEST(2) {
            @Override
            public Direction getOppositeDirection() {
                return Direction.EAST;
            }
        };
    
        Direction(int code){
            this.code=code;
        }
        protected int code;
    
        public int getCode() {
            return this.code;
        }
    
        public abstract Direction getOppositeDirection();
    }
    
    0 讨论(0)
  • 2020-11-27 11:00
    public enum Direction {
        NORTH, EAST, SOUTH, WEST;
    
        public Direction getOppositeDirection(){
            return Direction.values()[(this.ordinal() + 2) % 4];
        }
    }
    

    Enums have a static values method that returns an array containing all of the values of the enum in the order they are declared. source

    since NORTH gets 1, EAST gets 2, SOUTH gets 3, WEST gets 4; you can create a simple equation to get the opposite one:

    (value + 2) % 4

    0 讨论(0)
  • 2020-11-27 11:01

    For a small enum like this, I find the most readable solution to be:

    public enum Direction {
    
        NORTH {
            @Override
            public Direction getOppositeDirection() {
                return SOUTH;
            }
        }, 
        SOUTH {
            @Override
            public Direction getOppositeDirection() {
                return NORTH;
            }
        },
        EAST {
            @Override
            public Direction getOppositeDirection() {
                return WEST;
            }
        },
        WEST {
            @Override
            public Direction getOppositeDirection() {
                return EAST;
            }
        };
    
    
        public abstract Direction getOppositeDirection();
    
    }
    
    0 讨论(0)
  • 2020-11-27 11:02

    Yes we do it all the time. You return a static instance rather than a new Object

     static Direction getOppositeDirection(Direction d){
           Direction result = null;
           if (d != null){
               int newCode = -d.getCode();
               for (Direction direction : Direction.values()){
                   if (d.getCode() == newCode){
                       result = direction;
                   }
               }
           }
           return result;
     }
    
    0 讨论(0)
提交回复
热议问题