在阅读Effective Java时,我遇到了“使用枚举而不是int
常量”的建议。在目前的项目中,我正在做类似下面的事情:
int COL_NAME = 0;
int COL_SURNAME = 1;
table[COL_NAME] = "JONES"
我将如何使用枚举来实现此目的?由于我被迫使用的接口,我必须使用int
作为我的索引。上面的例子只是一个例子。我实际上使用的API为{1}}索引值。
答案 0 :(得分:50)
将一个有用的模式与反模式一起应用通常会失败; - )
如果您希望将int
常量替换为enum
值,则使用数组表示非实际数组类数据时会出现问题。
干净(呃)解决方案类似于EnumMap
,其值为enum
。
如果您绝对必须,可以使用table[COL_NAME.ordinal()]
。
如果某些API强制您传递int
值,但您可以控制实际值(即您可以传递自己的常量),那么您可以切换到在代码中使用enum
值并仅在代码与API接口的位置转换为enum
。 enumValue.ordinal()
的反向操作是EnumClass.values()[ordinal]
)。
答案 1 :(得分:6)
听起来你正在尝试使用EnumMap。这是一个包含值数组的Map。
enum Column {
NAME, SURNAME
}
Map<Column, String> table = new EnumMap<Column, String>(Column.class);
table.put(Column.NAME, "JONES");
String name = table.get(Column.NAME);
如果使用POJO,这会更简单。
classPerson {
String name;
String surname;
}
Person person = new Person();
person.name = "JONES";
String name = person.name;
答案 2 :(得分:1)
取决于要求。您可以使用Enum.ordinal()
将枚举转换为int。
请注意,无法直接传递Enum作为索引。
编辑:
另一种可能性是使用Map<YourEnum, String> map
,然后使用map.get(EnumValue)
。
答案 3 :(得分:1)
由于您必须使用该表,因此无法实际使用EnumMap
,我个人认为最好的解决方案是坚持使用您所拥有的。在枚举中,元素的序数值不应该具有任何内在含义,而在它们的情况下它们也是如此,因为它们被用作表中的索引。
你遇到的问题不在于你没有使用枚举,而是需要魔术值来从表中提取列数据。在这种情况下,使用整数常量是作业的正确工具,除非您能够解决该表的基本问题。
现在,您可以通过将表包装在您自己的类中来访问它,并使用枚举进出该类来解决它。但是这引入了更多代码,另一层间接并且实际上并没有为你解决任何问题,除了枚举比int值列表更容易维护(因为你必须维护你现在写的包装器而大大抵消了) )。
如果您正在编写其他人将使用的公共API,您可以考虑这项工作,因为它将避免让它们依赖于某些可能随时间变化的神奇值(紧密耦合会破坏事物)。如果你是,那么内部使用EnumMap
的包装器可能就好了。
否则,保持原样。
答案 4 :(得分:1)
根据数组的值,您可能正在查看对象。例如,如果您的数组看起来像这样
person[FIRST_NAME] = "Jim Bob"
person[SURNAME] = "Jones"
person[ADDRESS] = "123 ABC St"
person[CITY] = "Pleasantville"
...
然后你真正想要的是这样的
Person jimBob = new Person("Jim Bob", "Jones");
jimBob.setAddress("123 ABC St", "Pleasantville", "SC");
....
答案 5 :(得分:0)
我也遇到过这个问题,来自C ++世界,我没想到会遇到这个问题。
枚举的美妙之处在于它可以创建一系列具有唯一值的相关常量,其中实际值无关紧要。它们的使用使代码更容易阅读,并防止变量被设置为无效的枚举值(特别是在Java中),但在这种情况下,这是一个很大的痛苦。虽然你可能有“enum Pets {CAT,BIRD,DOG}”并且并不真正关心CAT,BIRD和DOG实际代表什么价值,但它写得如此美好和干净: myPets [CAT] =“Dexter”; myPets [BIRD] =“波莉”; MyPets [DOG] =“Boo-Rooh”;
在我的情况下,我最终写了一个转换函数,你传入一个枚举值,然后我返回一个常量。我讨厌用激情做这件事,但这是我所知道的唯一一种保持枚举方便和错误检查的清洁方式。
private int getPetsValue(Pets inPet) {
int value = 0;
switch (inPet) {
case CAT: value = 0; break;
case BIRD: value = 1; break;
case DOG: value = 2; break;
default:
assert(false);
value = 0;
break;
}
return value;
}
答案 6 :(得分:0)
您可以使用如下构造函数定义enum
:
public enum ArrayIndex {
COL_NAME(0), COL_SURNAME(1);
private int index;
private ArrayIndex(int index) {
this.index = index;
}
public int getIndex() {
return this.index;
}
};
然后像这样使用它:
public static void main (String args[]) {
System.out.println("index of COL_NAME is " + ArrayIndex.COL_NAME.getIndex());
}