2012-02-23 8 views
5

Me gustaría hacer referencia a una matriz con un tipo de enumeración. Esta es una cosa bastante estándar en C++ (mi origen), sin embargo, no estoy seguro si esto es posible/deseable en Java.Java: Usar una enumeración como referencia de matriz

Por ejemplo, me gustaría tener una enumeración tales como:

public enum Resource { 
    COAL, 
    IRON 
} 

Luego, más tarde me gustaría hacer referencia a este aspecto:

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

no quiero hacer Amount y Price campos de Resource como me gustaría una lista de objetos (pedidos de recursos) agrupados por el tipo de recurso. Asignar manualmente un int para cada tipo de Resource no es mejor que public static int final BLAH Creo, nada ganado.

En esencia, estoy buscando la enumeración de C++ que marca las cosas. Me doy cuenta de que esta podría ser la forma "incorrecta" de hacer las cosas en Java, así que siéntete libre de apuntarme en la dirección del ethos correcto de Java.

Respuesta

12

En C++, una enumeración es efectivamente un alias para un número entero. En Java, son objetos "adecuados", por lo que no puede usarlos como referencia de matriz.

Si quiere buscar el valor en su matriz que está asociado con un objeto enumerativo particular, ¡eso me suena a un Mapa! ¿Qué hay de reemplazar esas matrices con un EnumMap<Resource, Double>?

La clase EnumMap está optimizada para su uso con claves enum, de modo que termine usando una matriz introducida en el valor ordinal (entero) de las enums detrás de las escenas. Por lo tanto, es mucho más rápido que un hashmap de propósito general, y obtienes la velocidad de una solución basada en arreglos con la expresividad semántica de un Map; es lo mejor de ambos mundos.

+0

Ahhh! Esto es exactamente lo que me gustaría, ¡muchas gracias! – Cramer

-1

Por desgracia, tendrá una sintaxis un poco más largo:

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

Si eso no es de su agrado, las constantes pueden ser su única opción, es decir

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

} 

Espero que ayude.

+1

Realmente no debería usar 'ordinal()' - si uno agrega otro campo en 'enum', o incluso reordenarlo alfabéticamente, su código se romperá y será casi imposible averiguar por qué. Un 'Map' es una solución mucho más elegante y similar a Java. – Marcelo

+0

Quizás no ... pero responde la pregunta que hizo Cramer. –

+0

Es (algo así) lo es, pero también es * "la forma 'incorrecta' de hacer cosas en Java" *. – Marcelo

1

Puede hacer casi eso. A diferencia de C++, donde enum es solo un int, Java es enum clase. Entonces no puedes usarlo como un índice de matriz. Pero cada elemento de la enumeración tiene ordinal() que es int, por lo que puede decir

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

pero que tienen un mejor enfoque. Puede agregar métodos a enum, por lo que se verá así:

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

Creo que este enfoque es mucho mejor.

1

Cada elemento de la enumeración de Java tiene un ordinal asociado a él, indexada desde cero en base a la orden de la definición de la enumeración. Solo use, p.

COAL.ordinal() 

Sin embargo, me suena como que sería mejor crear un ejemplo de clase Haga un pedido con los campos Importe y Precio y luego conserve una colección de aquellos, p. en un Mapa indexado por los elementos enum.

p. Ej.

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

Los mapas son muy buenos para obtener datos más dinámicos. Pero también tiene que codificar todas las comprobaciones para nombres dobles, valores dobles, nombres/valores existentes y todas las cosas. E incluso en este caso, si comete el error, se encontrará solo en tiempo de ejecución.

Para obtener datos más estáticos, utilice mejor las enumeraciones no primitivas, pero new type enums from Java 6. Ellos son excelentes! Y los errores serán encontrados por el compilador.

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

Pero mejor variante es:

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=... 

Puede utilizar su nombre.

Se podría hacer el ciclo a través de todos enumeración:

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