Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用枚举';在Java中索引数组的顺序值是多少?_Java_Enums - Fatal编程技术网

使用枚举';在Java中索引数组的顺序值是多少?

使用枚举';在Java中索引数组的顺序值是多少?,java,enums,Java,Enums,我有两个阵列:墙和邻居 public boolean[] walls = new boolean[4]; public Cell[] neighbors = new Cell[4]; 我有一个枚举: enum Dir { North, South, East, West } 现在,我希望能够通过他们的方向访问墙壁或邻居,这样我就不必传递一堆神奇的索引 然而,当我阅读Enum.ordinal()的文档时,它说程序员几乎不会使用这种方法,这使我认为不应该以这种方式

我有两个阵列:墙和邻居

public boolean[] walls = new boolean[4];
public Cell[] neighbors = new Cell[4];
我有一个枚举:

enum Dir
{
    North,
    South,
    East,
    West
}
现在,我希望能够通过他们的方向访问墙壁或邻居,这样我就不必传递一堆神奇的索引

然而,当我阅读Enum.ordinal()的文档时,它说程序员几乎不会使用这种方法,这使我认为不应该以这种方式使用它

我想做一些类似的事情:

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

我应该恢复使用索引值设置为北、南、东、西的静态常量,还是使用枚举的序数方法?

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


但是,如果您的使用变得更加复杂,您可能需要使用EnumMap来代替,正如所建议的那样。

在一个重要的问题上,最好为您的邻居使用EnumMap:

Map<Dir, Cell> neighbours = 
    Collections.synchronizedMap(new EnumMap<Dir, Cell>(Dir.class));

neighbours.put(Dir.North, new Cell());

for (Map.Entry<Dir, Cell> neighbour : neighbours.entrySet()) {
    if (neighbour.isVisited()) { ... }
}

etc..

使用枚举的序号取决于隐式顺序。我喜欢显式的,特别是当你使用整数值作为数组的索引,将值和意义联系起来的时候


因此,在这种情况下,我会选择使用
最终静态int NORTH=0
,等等。

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


如果没有持久化数组或以任何其他方式使自己依赖于不同版本的枚举类,则可以安全地使用
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;
  }
}
从这里可以很容易地查找到方向的索引(通过在静态块中创建一个映射以实现紧凑持久性;在静态块中执行唯一性检查等)。

JavaDoc说

大多数程序员不会使用 此方法。它设计用于 复杂的基于枚举的数据 结构,例如枚举集和 枚举图

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


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

我强烈建议不要这样做,因为顺序值基于java代码中的顺序

使用ordinal()会使代码很难维护,特别是在某种形式的持久性进入等式时

例如,如果您决定添加对角线方向,如西北、东南。 如果您使用的是ordinal(),则必须将它们添加到列表的底部,否则以前的南方可能会变成北方

ie您可以将enyum更改为,而无需(可能)更改功能

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)

EnumSet
用于
walls
。可能不需要对其进行同步。虽然显示的代码在这种情况下是有效的,但大多数代码有时会发生更改,这很容易使其成为无效情况。
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;
  }

}
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;
  }
}
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)