2012-03-08 5 views
6

Java утверждает, что порядковое начального значения 0. Могу ли я считать, что, когда я создаю перечисление как это:Можно ли считать, что перечисления Java автоматически увеличиваются на 1?

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

То, что порядковое TUESDAY всегда 1, что из WEDNESDAY всегда 2, .. .?


Я буду более конкретным. Я объявляю перечисление:

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

Теперь есть способ поворота на 90 градусов (по часовой стрелке). Это одна линии с порядковыми:

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

Если бы я не использовать порядковый я бы использовать операторы переключателя или условия:

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

Есть несколько преимуществ использования порядковых:

  • сокращенный код
  • более быстрый код (неграмотный)
  • если направление (например, DOWN_LEFT) реализация не обязательно должна изменяться, если вы положили новое направление в нужное место

Как вы думаете?

+2

Если это имеет значение (например, для пользовательской сериализации), в любом случае вам будет лучше с явным сопоставлением. Просто создайте 'EnumMap 'или дайте' Direction' поле 'int'. –

+0

Я предпочел бы держать его в чистоте. Это для школы, но технически мы еще не использовали перечисления, и EnumMap может быть немного экстремальным, поскольку мы еще не узнали о массивах: D. – Fatso

+0

Ваше понятие о чистоте немного ошибочно :-). Опираясь на порядковый номер, было бы очень грязным способом кодировать это. –

ответ

7

Да - см javadoc:

Возвращает порядковый номер этой константы перечисления (его положение в своем перечислений декларации, в которой начальная константа присваивается порядковый номер, равный нулю).

+0

Я не понимаю: это только утверждает, что порядковый номер исходной константы равен нулю, а не то, что вторая константа имеет порядковый номер 1 или что третья константа имеет порядковый номер 2, ... – Fatso

+0

@Korion "свою позицию в объявлении перечисления », начиная с 0. Итак, MONDAY.ordinal() == 0, TUESDAY.ordinal() == 1 и т. д. – assylias

+0

Правильно, моя ошибка. Большое спасибо! – Fatso

2

Да. Однако полагаться на это не самая лучшая идея, если вы когда-либо захотите изменить порядок или добавить новые перечисления в разных местах или если вы найдете причину изменения существующего значения. Я считаю, что лучше дать им реальную ценность/значение, помимо их порядкового значения и имени.

+0

Хорошо, спасибо за ответ. Поскольку я использую стандартное перечисление, подобное выше, которое никогда не изменит его содержимое, я предполагаю, что сделаю это предположение. – Fatso

7

Да - но ваш код не должен полагаться на него, потому что тогда он сломается, когда кто-то вставит катаклизм.

+0

Верно, но перечисление всегда останется таким же в моем случае. – Fatso

+5

@ Корион: известные последние слова ... –

+0

Вы правы: D. На самом деле, я перечисляю {UP, RIGHT, DOWN, LEFT}, но я думаю, что технически учитель может меня укусить и добавить такие направления, как DOWN_LEFT, UP_RIGHT, ... – Fatso

3

Вы можете также применять индексы, как это:

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

    private int value;  

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

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

Да, однако, опираясь на это делает ваш код ломкими. Если вы когда-либо измените порядок констант в перечислении или добавите константы между ними, ординалы некоторых констант изменятся. Поэтому, например, не рекомендуется хранить порядковые номера в базе данных или файле, потому что, если ваш исходный код изменяется, данные в базе данных или файле больше не будут совместимы с вашим измененным кодом.

Более надежное решение заключается в явном хранении кодов с каждой из ваших констант. Например:

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

Проблема с ординалами заключается в том, что они зависят от порядка объявления значений перечисления.Если в какой-то момент новое количество добавляется к перечислению, и оно добавляется в середине других, тогда ординалы будут меняться, что приведет к аннулированию всего кода, зависящего от определенного порядкового значения.

Если вы абсолютно необходимо назначить фиксированное число к порядковым значением, это может быть полезным:

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

В приведенном выше фрагменте кода атрибут code связан с каждым значением перечисления, и вы можете быть уверены, что он всегда будет иметь одно и то же значение - тот, который передается в конструкторе.

 Смежные вопросы

  • Нет связанных вопросов^_^