Sunday, October 27, 2013

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 instantiated, but it illustrates my point). Is this possible in Java?
Here is the code:
public enum Direction {

     NORTH(1),
     SOUTH(-1),
     EAST(-2),
     WEST(2);

     Direction(int code){
          this.code=code;
     }
     protected int code;
     public int getCode() {
           return this.code;
     }
     static Direction getOppositeDirection(Direction d){
           return new Direction(d.getCode() * -1);
     }
}
share|improve this question
 
Just use a switch. You only have 4 cases. –  Sotirios Delimanolis Sep 18 at 22:56 
1 
By the way, d.getCode() * -1 == -d.getCode() –  Doorknob Sep 18 at 22:59
 
Chapter 6 (in 2E, at least) of Bloch's Effective Java might be of interest, and highly recommended. – jedwards Sep 18 at 23:05 

4 Answers

How about
public enum Direction {

    NORTH, SOUTH, EAST, WEST;

    private Direction oposite;

    static {
        NORTH.oposite = SOUTH;
        SOUTH.oposite = NORTH;
        EAST.oposite = WEST;
        WEST.oposite = EAST;
    }

    public Direction getOppositeDirection() {
        return oposite;
    }

}
share|improve this answer
1 
Nice solution :) –  Melih AltıntaÅŸ Sep 18 at 23:03
 
I was about to whip up an .values()[ordinal()] hack but this approach is much more robust – jedwards Sep 18 at 23:04
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();

}
share|improve this answer
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();
}
share|improve this answer
Yes we do it 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;
 }
share|improve this answer

No comments: