2012-03-08 9 views
6

Java establece que el ordinal del valor inicial es 0. ¿Puedo asumir que cuando se crea una enumeración de esta manera:¿Puedo suponer que las enumeraciones de Java aumenten automáticamente en 1?

public enum Direction {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, ...} 

Que el ordinal de TUESDAY es siempre 1, la de siempre WEDNESDAY 2, .. .?


Voy a ser un poco más específico. Estoy declarando una enumeración:

public enum Direction {UP,RIGHT,DOWN,LEFT} 

Ahora hay un método para girar 90 grados (a la derecha). Es una línea con los ordinales:

direction = Direction.values()[direction.ordinal()+1 % Direction.values().length]; 

Si yo no usaría los ordinales que tendría que utilizar las declaraciones o las condiciones de conmutación:

switch (direction) { 
    case LEFT:newdirection = Direction.UP; 
    break; 
    etc... 
} 

Hay un par de ventajas de utilizar los ordinales:

  • código más corto
  • código más rápido (negligeable)
  • si a dirección se añade (por ejemplo DOWN_LEFT) la puesta en práctica no necesariamente tiene que cambiar si se pone la nueva dirección en el lugar correcto

¿Qué opinas?

+2

Si es importante (por ejemplo, para la serialización personalizada), de todos modos, sería mejor realizar una asignación explícita. Solo crea un 'EnumMap ' o dale a 'Direction' un campo' int'. –

+0

Prefiero mantenerlo limpio. Es para la escuela, pero técnicamente aún no hemos usado enumeraciones, y EnumMap podría ser un poco extremo ya que ni siquiera aprendimos acerca de las matrices: D. – Fatso

+0

Tu noción de limpieza está un poco equivocada :-). Confiar en ordinal sería una forma extremadamente desordenada de codificar esto. –

Respuesta

7

Sí - ver javadoc:

Devuelve el ordinal de esta constante de enumeración (su posición en su declaración de enumeración, donde la constante inicial se le asigna un ordinal de cero).

+0

No entiendo: esto solo indica que el ordinal de la constante inicial es cero, no que la segunda constante tenga el ordinal 1, o que la tercera constante tenga el ordinal 2, ... – Fatso

+0

@Korion "su posición en su declaración enum ", empezando por 0. Entonces MONDAY.ordinal() == 0, TUESDAY.ordinal() == 1 etc. – assylias

+0

Correcto, mi error. ¡Muchas gracias! – Fatso

2

Sí. Sin embargo, confiar en eso no es la mejor idea si alguna vez desea reordenar o agregar nuevas enumeraciones en diferentes lugares, o si encuentra un motivo para cambiar un valor existente. Me parece mejor darles un valor/significado real además de su valor ordinal y su nombre.

+0

Muy bien, gracias por la respuesta. Como estoy usando una enumeración estándar como la de arriba que nunca cambiará su contenido, supongo que voy a hacer la suposición. – Fatso

7

Sí, pero su código no debería depender de él porque se romperá cuando alguien inserte Caturday.

+0

Es cierto, pero la enumeración siempre será la misma en mi caso. – Fatso

+5

@Korion: últimas palabras famosas ... –

+0

Tienes razón: D. Mi enumeración es en realidad {ARRIBA, DERECHA, ABAJO, IZQUIERDA}, pero supongo que técnicamente el maestro podría molestarme y agregar direcciones como DOWN_LEFT, UP_RIGHT, ... – Fatso

3

También puede hacer cumplir los índices de esta manera:

enum Direction { 
    MONDAY(1), 
    TUESDAY(2); 
    // etc... 

    private int value;  

    private Direction(int value) { 
    this.value = value; 
    } 

    public int getValue() { 
    return value; 
    } 
} 
4

Sí, sin embargo, basándose en esto hace que su código frágil. Si alguna vez cambia el orden de las constantes en la enumeración o agrega constantes entre ellas, los ordinales de algunas de las constantes cambiarán. Por lo tanto, no es una buena idea, por ejemplo, almacenar números ordinales en una base de datos o un archivo, porque si su código fuente cambia, los datos en la base de datos o archivo ya no serán compatibles con su código modificado.

Una solución más robusta es almacenar códigos explícitamente con cada una de sus constantes. Por ejemplo:

public enum Status { 
    NEW(0), 
    PROCESSING(1), 
    OK(2), 
    ERROR(99); 

    private final int code; 

    private Status(int code) { 
     this.code = code; 
    } 

    // Get the code for an enum constant 
    public int getCode() { 
     return code; 
    } 

    // Given a code, get the corresponding enum constant 
    public static Status fromCode(int code) { 
     for (Status s : Status.values()) { 
      if (s.code == code) { 
       return s; 
      } 
     } 

     throw new IllegalArgumentException("Invalid code: " + code); 
    } 
} 
1

El problema con los ordinales es que dependen del orden de declaración de los valores enum.Si en algún momento se agrega un nuevo valor a la enumeración y se agrega en medio de los demás, los ordinales cambiarán, invalidando todo el código que dependía de un valor ordinal específico.

Si es absolutamente necesario asignar un número fijo a un valor ordinal, esto podría ser de utilidad:

enum Directions { 
    NORTH(1), 
    SOUTH(2), 
    WEST(3), 
    EAST(4); 
    private int code; 
    Directions(int code) { 
     this.code = code; 
    } 
    public int getCode() { 
     return code; 
    } 
} 

En el fragmento anterior, un atributo code se asocia a cada valor de la enumeración, y usted puede estar seguro que siempre tendrá el mismo valor, el que pasó en el constructor.

Cuestiones relacionadas