2012-02-23 11 views
5

列挙型の配列を参照したいと思います。これはC++(私の起源)のかなり標準的なことですが、これがJavaで可能か望ましいかはわかりません。Java:配列参照として列挙型を使用する

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

私はAmountをしたくないと:後、私は次のように参照したいその後

public enum Resource { 
    COAL, 
    IRON 
} 

:たとえば、私は、列挙型などを持っていると思い

PriceフィールドはResourceです。リソースタイプ別にグループ化されたオブジェクトのリスト(リソースの注文)が必要です。 Resourceの各タイプにintを手動で割り当てることは、public static int final BLAHよりも優れているわけではありません。

本質的に、私は物事をタグ付けするC++のenumを探しています。私は、これがJavaでのことを「間違った」方法である可能性があることを認識しています。正しいJavaのエモスの方向に私を指差してください。

答えて

12

C++では、enumは事実上整数のエイリアスです。 Javaでは、それらは「適切な」オブジェクトです。そのため、配列参照として使用できません。

特定の列挙型オブジェクトに関連付けられた配列の値を検索する場合は、Map to meのように聞こえます!これらの配列をEnumMap<Resource, Double>に置き換えるのはどうですか?

EnumMapクラスは列挙型キーと共に使用するように最適化されているため、背後で列挙型の序数(整数)値をキーにした配列を使用することになります。したがって、汎用ハッシュマップよりもはるかに高速であり、意味表現がMapである配列ベースのソリューションの速度が得られます。これは、両方の世界で最高です。

+0

ああ!これはまさに私が欲しいものです、ありがとう! – Cramer

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

} 

お役に立てば幸いです。

+1

'enum'に別のフィールドを追加する場合や、アルファベット順に並べ替える場合は、あなたのコードが壊れてしまい、その理由を理解することがほとんど不可能になります。 'Map'ははるかに洗練されたJavaのようなソリューションです。 – Marcelo

+0

おそらくそうではありません...しかし、それはCramerが持っていた質問に答えます。 –

+0

それはやっているのですが、「Javaでのやり方が間違っています」*。 – Marcelo

1

ほとんど可能です。 enumがちょうどintであるC++とは対照的に、Javaのenumはクラスです。したがって、配列のインデックスとして使用することはできません。しかし、すべての列挙型の要素はintですordinal()を持っているので、あなたは

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

を言うことができますしかし、あなたはより良いアプローチを持っています。 enumにメソッドを追加すると、次のようになります。

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

私はこのアプローチがはるかに優れていると思います。

1

各Java列挙型要素は、列挙で定義の順序に基づいて、ゼロからインデックス付け、それに関連付けられた順序を有しています。ちょうど例えば使用する

COAL.ordinal() 

しかし、クラスを作成した方が良いと思うように聞こえます。金額と価格の欄を指定して注文し、次にそれらのコレクションを保管します。 enum要素によってインデックス付けされたマップ内の

Map<Resource, Order> orders = new HashMap<Resource, Order>(); 
orders.put(Resource.COAL, new Order(price, amount)); 
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; 
} 
関連する問題