Перечисляемые значения (). Длина по сравнению с частным полем - PullRequest
54 голосов
/ 16 ноября 2009

У меня есть перечисление как это:

public enum Configuration {
    XML(1),
    XSLT(10),
    TXT(100),
    HTML(2),
    DB(20);

    private final int id;
    private Configuration(int id) {
        this.id = id;
    }
    public int getId() { return id; }
}

Иногда мне нужно проверить, сколько полей у меня в перечислении. Какое лучшее решение? Должен ли я использовать метод «values ​​(). Length»? Или, может быть, я должен создать постоянное поле в перечислении следующим образом:

public enum Configuration {
    XML(1),
    XSLT(10),
    TXT(100),
    HTML(2),
    DB(20);

    private final int id;
    private Configuration(int id) {
        this.id = id;
    }
    public int getId() { return id; }

    public static final int Size = 5;
}

Какое самое быстрое и элегантное решение?

Ответы [ 4 ]

100 голосов
/ 16 ноября 2009

Использование values().length будет создавать новую копию массива каждый раз, когда вы вызываете его. Иногда я создаю свой собственный List (или набор, или карту, что мне нужно), чтобы избежать этого бессмысленного копирования. Я бы не стал бы жестко кодировать его, хотя ... если вам нужен только размер, я бы просто использовал:

private static final int size = Configuration.values().length;

в конце. К моменту оценки все значения будут инициализированы. Это позволяет избежать проблем с СУХОЙ и непоследовательностью, поднятых в других ответах.

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

Альтернативой использованию values() является использование EnumSet.allOf().size(), которое для небольших перечислений будет довольно дешевым, но опять же, оно не так читабельно, как просто наличие поля size.

9 голосов
/ 16 ноября 2009

Я бы порекомендовал использовать values().length. Это гораздо более элегантно, и снижение производительности по сравнению с использованием константы будет незначительным. Кроме того, вы исключаете риск того, что константа когда-либо выйдет за рамки фактической длины перечисления.

8 голосов
/ 16 ноября 2009

Сохраняя счет, вы нарушаете принцип DRY , поэтому, если у вас нет веских причин, вам не следует.

4 голосов
/ 28 февраля 2016

Другой подход заключается в использовании константы, инициализированной поверх метода values ​​().

public enum Colors {
    BLUE, GREEN, FUCHSIA;
    public static int COUNT = Colors.values().length;
}

Таким образом, у вас автоматически обновляется константа, и вы по-прежнему избегаете накладных расходов «values ​​()».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...