Java:使用枚举作为数组引用

时间:2012-02-23 09:28:13

标签: java arrays enums

我想引用一个枚举类型的数组。这在C ++(我的起源)中是一个非常标准的东西,但是我不确定这在Java中是否可行/可取。

例如,我希望有一个枚举如:

public enum Resource {
    COAL,
    IRON
}

然后我想像这样引用:

Amount[COAL] // The amount of coal
Price[IRON]  // The price of iron

我不希望将AmountPrice字段设为Resource,因为我希望按资源类型分组对象列表(资源订单)。手动为每种类型的Resource分配一个int并不比public static int final BLAH更好,我觉得没有任何好处。

本质上,我正在寻找标记事物的C ++枚举。我意识到这可能是用Java做事的“错误”方式,所以请随意指出正确的Java风格。

6 个答案:

答案 0 :(得分:13)

在C ++中,枚举实际上是整数的别名。在Java中,它们是“正确的”对象 - 这就是为什么你不能将它们用作数组引用的原因。

如果你想在数组中查找与特定枚举对象相关联的值 - 这听起来像是我的地图!如何用EnumMap<Resource, Double>替换这些数组?

EnumMap类已经过优化,可以与枚举键一起使用,这样它最终会使用在幕后的枚举'序数(整数)值上键入的数组。因此它比通用散列图快得多,并且您可以获得基于数组的解决方案的速度,其语义表达能力为Map - 这是两个世界中最好的。

答案 1 :(得分:1)

你几乎可以做到。与其中enum只是int的C ++相比,Java的enum是类。所以你不能用它作为数组的索引。但是每个枚举元素的ordinal()都是int,所以你可以说

amount[COAL.ordinal()]
price[IRON.ordinal()]

但是你有更好的方法。可以为枚举添加方法,所以它看起来像:

IRON.price(amounts)
COAL.amount(prices)

我认为这种方法要好得多。

答案 2 :(得分:1)

每个Java枚举元素都有一个与之关联的序数,根据枚举中的定义顺序从零开始索引。只需使用例如

COAL.ordinal()

但是,听起来我觉得你最好创建一个类,例如订购金额和价格的字段,然后保留这些字段的集合,例如在由枚举元素索引的地图中。

e.g。

Map<Resource, Order> orders = new HashMap<Resource, Order>();
orders.put(Resource.COAL, new Order(price, amount));

答案 3 :(得分:0)

我认为您正在寻找EnumMap,http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumMap.html

它不完全是一个数组,但由于键是一个枚举,它仍然是空间效率。

最终结果如下:

amount.get(Resource.COAL)

答案 4 :(得分:0)

地图非常适合更多动态数据。但是你还必须编写所有检查双重名称,双值,现有名称/值和所有东西的代码。即使在这种情况下,如果您执行错误,也只能在运行时找到它。

对于更多静态数据,最好使用非原始枚举,但new type enums from Java 6。他们很棒!编译器会发现错误。

public enum Resource{
    COAL(0), IRON(1);
    int index;
    private Resource(int index){
        this.index=index;
    }
}
...
amount[Resource.COAL.index]=...

但更好的变体是:

public enum Resource{
    COAL(538,0.5f), IRON(115,1.5f);
    int amount;
    float price;
    private Resource(int amount, float price ){
        this.amount=amount;
        this.price=price;
    }
}
...
Resource.COAL.amount=...

您可以使用他们的名字。

你可以通过所有枚举进行循环:

for(Resource resourceType: Resource.values()) { 
   String toOutput=resourceType.name()+" amount="+ resourceType.amount;
}

答案 5 :(得分:-1)

不幸的是,您需要稍长的语法:

Amount[COAL.ordinal()] // The amount of coal
Price[IRON.ordinal()]  // The price of iron

如果这不符合您的喜好,常数可能是您唯一的选择,即

public class Resource {
    public static final int COAL = 0;
    public static final int IRON = 1;

}

希望有所帮助。