使用 Enum 的序数值在 Java 中索引数组是不好的做法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1574580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it bad practice to use an Enum's ordinal value to index an array in Java?
提问by Scorcher84
I have two arrays: Walls and Neighbors.
我有两个数组:Walls 和 Neighbors。
public boolean[] walls = new boolean[4];
public Cell[] neighbors = new Cell[4];
and I have an Enum:
我有一个枚举:
enum Dir
{
North,
South,
East,
West
}
Now, I would like to be able to access walls or neighbors by their direction, so I don't have to pass around a bunch of magic indexes.
现在,我希望能够通过他们的方向访问墙壁或邻居,所以我不必传递一堆魔法索引。
However, when I was reading the documentation for Enum.ordinal() it said that programmers will have almost no use for this method which made me think it shouldn't be used in this way.
但是,当我阅读 Enum.ordinal() 的文档时,它说程序员几乎不会使用这种方法,这让我认为不应该以这种方式使用它。
I was thinking of doing something like:
我正在考虑做类似的事情:
List<Dir> availableDirections = new ArrayList<Dir>();
for(Dir direction : Dir.values())
if (!Neighbors[direction.ordinal()].Visited)
availableDirections.add(direction);
or even:
甚至:
return Neighbors[Dir.North.ordinal()];
Should I revert to using static constants for NORTH, SOUTH, EAST, WEST with the index value set to them or use an Enum's ordinal method?
我应该恢复对 NORTH、SOUTH、EAST、WEST 使用静态常量并将索引值设置为它们还是使用 Enum 的序数方法?
采纳答案by toolkit
On a tangential issue, it might be better to use an EnumMap for your neighbours:
在切线问题上,为您的邻居使用 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..
BTW: Enum instances should by convention be all caps,
顺便说一句:按照惯例,枚举实例应该全部大写,
enum Dir {
NORTH,
EAST,
SOUTH,
WEST
}
回答by Michael Myers
The documentation only says that mostprogrammers will have no use for the method. This is one case of legitimate use. Assuming your class controls both the enum and the array, there is no reason to fear the ordinal()
method for indexing the array (since you can always keep them in sync).
文档只说大多数程序员不会使用该方法。这是合法使用的一种情况。假设您的类同时控制 enum 和 array,则没有理由担心ordinal()
索引数组的方法(因为您可以始终保持它们同步)。
However, if your usage gets any more complicated, you will likely want to use an EnumMap
instead, as has been suggested.
但是,如果您的用法变得更加复杂,您可能希望使用 anEnumMap
来代替,正如所建议的那样。
回答by rsp
Using an enum's ordinal for your use depends on implicit order. I like to be explicit especially if you use the integer values as index into your array linking value to meaning.
使用枚举的序数取决于隐式顺序。我喜欢明确,特别是如果您使用整数值作为将值链接到含义的数组的索引。
In this case I would therefore opt to use final static int NORTH = 0
, etc.
在这种情况下,我会因此选择使用final static int NORTH = 0
等。
回答by Arne Burmeister
You can also enhance an enum (index clockwise):
您还可以增强枚举(顺时针索引):
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;
}
}
回答by PeterR
If you are not persisting the arrays or in any other way are making yourself dependent on different versions of your enum class, it's safe to use ordinal()
.
如果您没有持久化数组或以任何其他方式使自己依赖于枚举类的不同版本,那么使用ordinal()
.
If you want don't want to rely on the implicit ordering of the enum values, you could introduce a private index value:
如果你不想依赖枚举值的隐式排序,你可以引入一个私有索引值:
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;
}
}
From here it's easy to both allow for easy lookup of index to Direction (By creating a Map in a static block for compact persistence; Do uniqueness check in static block etc.
从这里开始,很容易允许轻松查找方向索引(通过在静态块中创建 Map 以实现紧凑持久性;在静态块中进行唯一性检查等。
回答by meriton
The JavaDoc says
JavaDoc 说
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.
大多数程序员不会使用这种方法。它设计用于复杂的基于枚举的数据结构,例如 EnumSet 和 EnumMap。
I think they want to say that most programmers will prefer using an EnumMap or EnumSet over manually indexing into an array. They certainly don't mean that you should substitute a couple of integer variables for your enum, as you would lose type safety in doing so.
我认为他们想说大多数程序员更喜欢使用 EnumMap 或 EnumSet 而不是手动索引到数组中。它们当然并不意味着您应该用几个整数变量替换您的枚举,因为这样做会失去类型安全性。
If you need the flexibility to be able to reorder the enum constants without affecting the order in the array you can isolate the index into another field of the enum as has been described by Arne.
如果您需要灵活地重新排序枚举常量而不影响数组中的顺序,您可以将索引隔离到枚举的另一个字段中,如 Arne 所述。
回答by pvgoddijn
i strongly recommend against it because the Ordinal value is based on the order in your java code.
我强烈建议不要这样做,因为 Ordinal 值基于您的 Java 代码中的顺序。
The use of ordinal() will make you code very hard to maintain, especially if some form of persistence enters the equation.
使用 ordinal() 会使您的代码很难维护,尤其是当某种形式的持久性进入等式时。
for example if you decide to add diagonal directions like NORTH_WEST, SOUTH_EAST. if you are using ordinal(), you must add these at the bottom of your list or else what used to be SOUTH might become NORTH.
例如,如果您决定添加对角线方向,如 NORTH_WEST、SOUTH_EAST。如果您使用的是 ordinal(),则必须将它们添加到列表底部,否则以前的 SOUTH 可能会变成 NORTH。
ie you can change your enyum to without (possibly) changing functionality
即您可以将您的 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)