在Java Enum定义中使用序数

Sar*_*all 5 java enums ordinal

我注意到Java Enum文档说明了序数方法:

返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量的序数为零).大多数程序员都没有使用这种方法.它设计用于复杂的基于枚举的数据结构,例如EnumSet和EnumMap.

我理解在线的所有示例都建议不要使用ordinal索引到数组而是使用索引EnumMap.特别是有效Java的第33项 但我的问题是:在我的Enum定义中使用它是否可以?例如我的代码如下:

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];
  } 
}
Run Code Online (Sandbox Code Playgroud)

如你所见,我正在使用序数(),以便我可以循环指示(并返回下一个相关方向).例如旋转90度NORTH将返回EAST.

但是我知道使用序数不是好习惯,所以我想知道是否有更好的方法来做到这一点,同时仍然保持代码大小并保持可读性.

任何建议我都非常感激!

Old*_*eon 4

我想说这是完全可以接受的ordinal. 事实上,在我看来,它非常简洁。

ordinal关于在代码中不使用的注释enum只是为了阻止您这样做,因为大多数时候您可以使用 本身enum或 来EnumMap代替。

您的引用警告EffectiveJava您不要这样做,因为选择正确的int值用作数组的偏移量是令人担忧的,而且通常是不必要的。在您的情况下,这不适用,因为a)您做得正确,b)这是实现您正在寻找的功能的最简单的方法。