I notice that the Java Enum Documentation states the ordinal method:
Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero). Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data structures, such as EnumSet and EnumMap.
I understand all the examples online that suggest not to use ordinal
to index into an array but an EnumMap
instead. Particularly Item 33 of Effective Java
But my question is: is it ok to use it within my Enum
definition?
For example my code is as follows:
public enum Direction {
NORTH(0, 1), NORTH_EAST(1, 1), EAST(1, 0), SOUTH_EAST(1, -1),
SOUTH(0, -1), SOUTH_WEST(-1, 1), WEST(-1, 0), NORTH_WEST(-1, 1);
private final int xOffset;
private final int yOffset;
private final static int DEGREES = 360;
private Direction(int xOffset, int yOffset) {
this.xOffset = xOffset;
this.yOffset = yOffset;
}
public Position move(Position position) {
return new Position(position.getX() + xOffset, position.getY() + yOffset);
}
public Direction rotate(int degrees) {
int length = Direction.values().length;
int index = (ordinal() + (degrees / (DEGREES / length))) % length;
return Direction.values()[index];
}
}
As you can see I'm using ordinal() so that I can cycle through the directions (and return the next relevant direction). E.g. rotating 90 degrees from NORTH
will return EAST
.
However I know that using ordinal isn't good practice so I wondered if there is a better way to do this whilst still keeping the code size down and maintaining readability.
I'd be very appreciative for any advice!
I'd say this is a perfectly acceptable use of ordinal
. In fact it is, in my opinion, quite neat and simple.
The comments about not using ordinal
in your enum
code is merely to discourage you from doing so because most of the time you can use the enum
itself or an EnumMap
instead.
Your reference to EffectiveJava
is warning you against doing this because choosing the correct int
to use as offset to an array is fraught and generally unnecessary. In your case that doesn't apply because a) You are doing it correctly and b) It is the simplest method to achieve the functionality you are looking for.
Your code would break if someone in the future would introduce new members is the enum, like WEST_FAR_AWAY(-10, 0). You need to estimate whether this is a "minor and acceptable flaw" or a "maintenance nightmare" depending on the requirements of your application...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With