在Java中使用数组索引的枚举

时间:2011-03-24 10:02:24

标签: java enums

在阅读Effective Java时,我遇到了“使用枚举而不是int常量”的建议。在目前的项目中,我正在做类似下面的事情:

int COL_NAME = 0;
int COL_SURNAME = 1;

table[COL_NAME] = "JONES" 

我将如何使用枚举来实现此目的?由于我被迫使用的接口,我必须使用int作为我的索引。上面的例子只是一个例子。我实际上使用的API为{1}}索引值。

7 个答案:

答案 0 :(得分:50)

将一个有用的模式与反模式一起应用通常会失败; - )

如果您希望将int常量替换为enum值,则使用数组表示非实际数组类数据时会出现问题。

干净(呃)解决方案类似于EnumMap,其值为enum

如果您绝对必须,可以使用table[COL_NAME.ordinal()]

如果某些API强制您传递int值,但您可以控制实际值(即您可以传递自己的常量),那么您可以切换到在代码中使用enum值并仅在代码与API接口的位置转换为enumenumValue.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");
....

请参阅Refactoring: Replace Array with Object

答案 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());
}