0

Сравнение: values() у Enum с длиной приватного поля

12

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

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;
}

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

3 ответ(ов)

1

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

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

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

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

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

0

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

0

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

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

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь