我注意到Java Enum Documentation表示了序数方法:
返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量的序数为零)。大多数程序员都没有使用这种方法。它设计用于复杂的基于枚举的数据结构,例如EnumSet和EnumMap。
我理解在线的所有示例都建议不要使用ordinal
来索引数组,而是使用EnumMap
。特别是Item 33 of Effective Java
但我的问题是:在我的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];
}
}
正如你所看到的,我正在使用序数(),以便我可以循环指示(并返回下一个相关方向)。例如。从NORTH
旋转90度将返回EAST
。
但是我知道使用序数不是一个好习惯,所以我想知道是否有更好的方法来做到这一点,同时仍然保持代码大小并保持可读性。
我非常感谢任何建议!
答案 0 :(得分:4)
我认为这是ordinal
完全可以接受的用法。事实上,在我看来,它非常简洁。
有关在ordinal
代码中未使用enum
的评论仅仅是为了阻止您这样做,因为大部分时间您都可以使用enum
本身或EnumMap
而不是。
您对EffectiveJava
的引用警告您不要这样做,因为选择正确的int
作为数组的偏移量是非常困难的,而且通常是不必要的。在你不适用的情况下因为a)你正确地做了这件事b)这是实现你正在寻找的功能的最简单的方法。
答案 1 :(得分:2)
如果将来有人会引入新成员,那么你的代码就会破坏,就像是WEST_FAR_AWAY(-10,0)。您需要根据申请的要求估计这是否是“轻微且可接受的缺陷”或“维护噩梦”......
答案 2 :(得分:1)
可以在我的Enum定义中使用它吗?
可以使用。但是不使用它并去EnumMap的原因在你提供的链接中有明确说明(引用修改,因为它引用了它的部分中描述的例子)
这个程序有效,甚至看起来很优雅,但外表可能是骗人的。就像编译器无法知道序数和数组索引之间的关系一样。如果你在某个地方进行了更改而忘记更新它,那么你的程序将在运行时失败。
如果你想把它包含在你的设计中,那么EnumMap似乎非常有效。