Сравнение: values() у Enum с длиной приватного поля
У меня есть перечисление, как показано ниже:
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 ответ(ов)
Использование values().length
будет создавать новую копию массива каждый раз при его вызове. Иногда я создаю свой собственный List
(или Set
, или Map
, в зависимости от того, что мне нужно), чтобы избежать этого бесполезного копирования. Но я бы не стал хардкодить это... если вам просто нужен размер, я бы использовал:
private static final int size = Configuration.values().length;
в самом конце. К моменту, когда это будет вычислено, все значения будут инициализированы. Это позволяет избежать проблем с соблюдением принципа DRY и несоответствия, о которых упоминалось в других ответах.
Конечно, это немного микрооптимизация... но в конечном итоге она приводит к более простому коду, на мой взгляд. Вызов values().length
из других мест не выражает то, что вас интересует, а именно только размер перечисления - тот факт, что вы получаете это через массив значений, является второстепенным и отвлекающим, как мне кажется.
Альтернативой использованию values()
может быть использование EnumSet.allOf().size()
, что для небольших перечислений будет довольно дешевым, но, опять же, это не так читаемо, как просто наличие поля size
.
Я бы рекомендовал использовать values().length
. Это гораздо более элегантный подход, и затраты на производительность по сравнению с использованием константы будут незначительными. Кроме того, вы устраняете риск того, что константа когда-либо станет несоответствующей фактической длине перечисления.
Другой подход — использовать константу, инициализированную на основе метода values()
.
public enum Colors {
BLUE, GREEN, FUCHSIA;
public static int length = Colors.values().length;
}
Таким образом, у вас будет автоматически обновляемая константа, и при этом вы избежите накладных расходов, связанных с вызовом values()
.
Сравнение членов enum в Java: использовать == или equals()?
Цикл for для перебора enum в Java
Можно ли наследовать перечисления для добавления новых элементов?
Jackson: Сериализация и десериализация значений enum в виде целых чисел
Являются ли имена перечислений (enum) в Java интернированными?