10

I have an enum class with the cardinal directions(North, East, South, West):

public enum Direction {
    NORTH,
    EAST,
    SOUTH,
    WEST;
}

Is there a way to be able to use multiple names for the same thing? For example something like this:

public enum Direction {
    NORTH or N,
    EAST or E,
    SOUTH or S,
    WEST or W;
}

In practice what I want is to be able and sign to a variable either N or NORTH and have the two operations be exactly the same.

Example:

Direction direction1=new Direction.NORTH;
Direction direction2=new Direction.N;
//direction1==direction2
Pithikos
  • 18,827
  • 15
  • 113
  • 136

3 Answers3

12
public enum Direction {
  NORTH,
  EAST,
  SOUTH,
  WEST,
  ;

  // Convenience names.
  public static final Direction N = NORTH;
  public static final Direction E = EAST;
  public static final Direction S = SOUTH;
  public static final Direction W = WEST;
}

is legal, but "N" will not work with the auto-generated valueOf method. I.e. Direction.valueOf("N") will throw an IllegalArgumentException instead of returning Direction.NORTH.

You also cannot write case N:. You have to use the full names in switches whose value is a Direction.

Other than that, the abbreviated form should work just as well as the full version. You can use Direction.N in EnumSets, compare it for equality Direction.N == Direction.NORTH, get its name() (which is "NORTH"), import static yourpackage.Direction.N;, etc.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
5

You could do something like this (East and West omitted).

public enum Direction {
    NORTH {
        @Override
        Direction getDirection() {
            return NORTH;
        }
    },
    N {
        @Override
        Direction getDirection() {
            return NORTH;
        }
    },
    SOUTH {
        @Override
        Direction getDirection() {
            return SOUTH;
        }
    },
    S {
        @Override
        Direction getDirection() {
            return SOUTH;
        }
    }   ;

    abstract Direction getDirection();
}

Then you could something like this

public void foo(Direction arg) {
  Direction d = arg.getDirection();
}

Then you will always be dealing with only NORTH, SOUTH, EAST, and WEST.

JustinKSU
  • 4,875
  • 2
  • 29
  • 51
  • 1
    1+. Haven't thought about that. – Anthony Accioly May 10 '11 at 22:29
  • 1
    But `N == NORTH` will return false. This means that you've always got to remember to use `getDirection()` which is cumbersome and makes your code fragile ... and probably more verbose than it was before you added `N` as an abbreviation. – Stephen C May 10 '11 at 23:47
  • @Stephen Agreed. It's not an ideal solution, but just "A" solution. – JustinKSU May 11 '11 at 14:57
0

Hum, maybe having a "client Enum" with variables that hold the actual "meaningful Enum"?

public enum Direction {
    NORTH(BaseDirection.NORTH),
    N(BaseDirection.NORTH),
    EAST(BaseDirection.EAST),
    E(BaseDirection.EAST),
    SOUTH(BaseDirection.SOUTH),
    S(BaseDirection.SOUTH),
    WEST(BaseDirection.WEST),
    W(BaseDirection.WEST);

    private BaseDirection baseDirection;

    private Direction(BaseDirection baseDirection) {
        this.baseDirection = baseDirection;
    }

    public BaseDirection getBaseDirection() {
        return baseDirection;
    }           
}

public enum BaseDirection {
    NORTH,
    EAST,
    SOUTH,
    WEST;
}

Kinda overkill, but you can expose Direction to client code and use getBaseDirection for actual logic.

Anthony Accioly
  • 21,918
  • 9
  • 70
  • 118
  • You'll need to do more if you want something like: N == NORTH to be true. – ChrisH May 10 '11 at 23:42
  • The problem with this is that N != NORTH. You would need to compare direction values using `equals`, and `switch(direction){...}` would need to use both alternatives. It kind of defeats the purpose of using enums. – Stephen C May 10 '11 at 23:42