Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use of ordinal inside Java Enum definition

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!

like image 714
Sarah Tattersall Avatar asked Feb 08 '13 09:02

Sarah Tattersall


2 Answers

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.

like image 169
OldCurmudgeon Avatar answered Oct 04 '22 16:10

OldCurmudgeon


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

like image 28
lbalazscs Avatar answered Oct 04 '22 14:10

lbalazscs