Есть ли C-подобный способ получить номер элемента из enum в java? - PullRequest
8 голосов
/ 04 мая 2010

Perhap это простой базовый вопрос

Имея перечисление

public enum TK{
        ID,GROUP,DATA,FAIL;
        }

Могу ли я получить номер заказа, например, ID = 0, GROUP = 2, DATA = 3, FAIL = 4?

Это путь к этому, но странный и длинный! = S

public enum TK{
        ID(0),GROUP(1),DATA(2),FAIL(3);

        int num;
        TK(int n)
        {
           this.num=n;
        }

        public int get()
        {
           return num;
        }

  };

чтобы получить числа, поэтому я пишу TK.ID.get (), TK.GROUP.get () и т. Д ... Мне это не нравится

есть лучший способ?

(перечисления C, макросы..Я скучаю по вам обоим)

спасибо

Ответы [ 5 ]

14 голосов
/ 04 мая 2010

ordinal() делает то, что вы хотите сделать. Это выдержка из документации:

Возвращает порядковый номер этой константы перечисления (ее позиция в объявлении enum, где начальной константе присвоен порядковый номер нуля). Большинство программистов не будут использовать этот метод. Он предназначен для использования сложными структурами данных на основе перечислений, такими как EnumSet и EnumMap ,

Джош Блох в Effective Java 2nd Edition идет дальше, чтобы объяснить, почему использование ordinal() является ужасной идеей. Вот несколько цитат, слегка отредактированных:

Никогда не получайте значение, связанное с перечислением, из его порядкового номера; вместо этого сохраните его в поле экземпляра. ( Элемент 31: Использовать поля экземпляров вместо ординалов ) Редко целесообразно использовать порядковые номера для индексации массивов: используйте EnumMap вместо. Общий принцип заключается в том, что прикладные программисты должны редко, если вообще когда-либо, использовать Enum.ordinal. ( Позиция 33: используйте EnumMap вместо порядкового индекса )

Твой "странный и долгий" путь - именно то, что предписано в пункте 31.

К счастью , Java - это не C. Java enum очень мощная и гибкая, поддерживается многими классами библиотек, и вы должны научиться использовать их вместо использования ordinal().

Посмотрите, например, EnumMap.

Специализированная Map реализация для использования с клавишами типа enum. Все ключи в карте enum должны принадлежать одному типу enum, который указан явно или неявно при создании карты. Карты Enum представляются внутри как массивы. Это представление чрезвычайно компактно и эффективно.

То есть вместо следующего (возможно, именно этого вы и хотели):

T[] arr = ...;
TK tk = ...;
T something = ...;

arr[tk.ordinal()] = something;

Вместо этого вы можете сделать:

Map<TK,T> map = new EnumMap<TK,T>(TK.class);
TK tk = ...;
T something = ...;

map.put(tk, something);

Книга также охватывает другое «традиционное» (ab) использование enum в C, то есть битовые поля (присвоение степеней 2 каждой константе и т. Д.). Ну, для этого Java имеет EnumSet вместо.

7 голосов
/ 04 мая 2010
2 голосов
/ 04 мая 2010
tk.ordinal()

- это способ сделать это, где tk - это экземпляр TK

http://java.sun.com/javase/6/docs/api/index.html?java/lang/Enum.html#ordinal()

2 голосов
/ 04 мая 2010

Вы можете использовать порядковый номер ()

1 голос
/ 04 мая 2010

http://java.sun.com/javase/6/docs/api/java/lang/Enum.html#ordinal()

открытый финальный int ординал ()
Возвращает порядковый номер этой константы перечисления (ее позиция в объявлении перечисления, где начальной константе присвоен порядковый номер нуля) Большинство программистов не будут использовать этот метод. Он предназначен для использования сложными структурами данных на основе перечислений, такими как EnumSet и EnumMap.

...