使用Enum的序数值来索引Java中的数组是不好的做法吗?

我有两个数组:Walls和Neighbors。

public boolean[] walls = new boolean[4]; public Cell[] neighbors = new Cell[4]; 

我有一个枚举:

 enum Dir { North, South, East, West } 

现在,我希望能够按照他们的方向访问墙壁或邻居,所以我不必传递一堆魔法索引。

但是,当我阅读Enum.ordinal()的文档时,它说程序员几乎没有使用这种方法,这让我认为它不应该以这种方式使用。

我想做的事情如下:

  List availableDirections = new ArrayList(); for(Dir direction : Dir.values()) if (!Neighbors[direction.ordinal()].Visited) availableDirections.add(direction); 

甚至:

 return Neighbors[Dir.North.ordinal()]; 

我应该恢复使用设置为索引值的NORTH,SOUTH,EAST,WEST的静态常量还是使用Enum的序数方法?

在切线问题上,为邻居使用EnumMap可能更好:

 Map neighbours = Collections.synchronizedMap(new EnumMap(Dir.class)); neighbours.put(Dir.North, new Cell()); for (Map.Entry neighbour : neighbours.entrySet()) { if (neighbour.isVisited()) { ... } } etc.. 

顺便说一句:按照惯例,枚举实例应该是全部大写,

 enum Dir { NORTH, EAST, SOUTH, WEST } 

您还可以增强枚举(顺时针索引):

 enum Dir { NORTH(0), SOUTH(2), EAST(1), WEST(3); private final int index; private Dir(int index) { this.index = index; } public int getIndex() { return index; } } 

文档只说大多数程序员都不会使用该方法。 这是合法使用的一个案例。 假设你的类控制枚举和数组 ,没有理由担心索引数组的ordinal()方法(因为你总是可以让它们保持同步)。

但是,如果你的用法变得更复杂,你可能会想要使用EnumMap ,正如所建议的那样。

JavaDoc说

大多数程序员都没有使用这种方法。 它设计用于复杂的基于枚举的数据结构,例如EnumSet和EnumMap。

我想他们想说大多数程序员更喜欢使用EnumMap或EnumSet而不是手动索引到数组中。 它们当然并不意味着您应该将几个整数变量替换为枚举,因为这样做会丢失类型安全性。

如果您需要灵活地能够重新排序枚举常量而不影响数组中的顺序,您可以将索引隔离到枚举的另一个字段中,如Arne所述。

如果您没有持久化数组或以任何其他方式使自己依赖于枚举类的不同版本,则使用ordinal()是安全的。

如果您不想依赖枚举值的隐式排序,可以引入私有索引值:

 public enum Direction { NORTH(0), SOUTH(1), EAST(2), WEST(3); private int _index; private Direction (int index_) { _index = index_; } public int getIndex() { return _index; } } 

从这里可以很容易地轻松查找到Direction的索引(通过在静态块中创建Map以实现紧凑的持久性;在静态块中执行唯一性检查等。

使用枚举的序数取决于隐式顺序。 我喜欢明确,特别是如果您使用整数值作为索引到您的数组链接值到意义。

在这种情况下,我会选择使用final static int NORTH = 0等。

我强烈建议不要使用它,因为Ordinal值是基于java代码中的顺序。

使用ordinal()将使代码非常难以维护,特别是如果某种forms的持久性进入等式。

例如,如果您决定添加对角线方向,例如NORTH_WEST,SOUTH_EAST。 如果您使用的是ordinal(),则必须在列表底部添加这些内容,否则以前可能会成为NORTH的内容。

即你可以改变你的enyum没有(可能)改变function

 N (is now 0 was 0) NE (is now 1) E (is now 2 was 1) SE (is now 3 ) S (is mow 4 was 2) SW (is now 5) W (is now 6 was 3)