Установка перечисления с использованием int, специфичного для этого перечисления?
Эй, все. Поэтому у меня есть набор перечислений и db с целыми числами, соответствующими этим перечислениям. Что-то вроде этого, например:
public static enum Day {
SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);
public final int fId;
private Day(int id) {
this.fId = id;
}
}
У меня также есть база данных, которая относится только к этим дням целыми числами, которые соответствуют их int в перечислении, указанном выше. То, что я хочу сделать, - это запросить базу данных, которая вернет целое число, а затем установите перечислитель для объекта на основе этого целого числа, возвращаемого из db. Я мог бы сделать что-то вроде этого:
public static Day getDay(int i) {
switch(i) {
case 1:
return Day.SUNDAY;
case 2:
return Day.MONDAY;
//And so on
}
}
Но для набора перечислений с более чем 100 перечислениями внутри этого не представляется очень практичным.
Так есть способ сделать это? Снова моя цель - просто вставить значение int и вернуть счетчик, не создавая новый метод для многих перечислений в этом наборе. Возможно, я должен просто сделать это своим классом, а не перечислителем, но я надеялся сделать это таким образом. Спасибо!
Ответы
Ответ 1
У перечислений есть встроенный идентификационный номер, "порядковый номер", который вы можете использовать для этой цели, если у вас есть простой способ получить от числа, которое представляет заданное значение в базе данных, в порядковый номер перечисление. Ординалы назначаются значениям перечисления в том порядке, в котором они объявлены в исходном файле, начиная с 0, поэтому в вашем примере SUNDAY
будет иметь порядковый номер 0, MONDAY
из 1 и т.д.
Чтобы использовать это, вам просто нужно преобразовать целое число, хранящееся в базе данных, в соответствующий порядковый номер, а затем использовать его для для доступа к значению перечисления. Итак, для вашего примера реализация может быть
private static Day[] values = Day.values();
public static Day getDay(int i) {
return values[i - 1];
}
Если порядок значений перечисления в соответствии с их идентификаторами базы данных является тем же самым порядком, в котором они объявлены в исходном коде, тогда вы можете в значительной степени использовать вышеуказанный метод as-is (за исключением изменения имени класса), В противном случае вам может понадобиться сделать что-то более сложное, чтобы сопоставить значения базы данных с ординалами; возможно, настроив массив, если отображение сильно нелинейно.
P.S. И, конечно, если вы это сделаете, не было бы пользы для поля fId
.
Ответ 2
Вот простая реализация, которая будет работать:
public static enum Day {
SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);
public final int fId;
private Day(int id) {
this.fId = id;
}
public static Day forInt(int id) {
for (Day day : values()) {
if (day.fId == id) {
return day;
}
}
throw new IllegalArgumentException("Invalid Day id: " + id);
}
}
Если вы знаете, что ваши перечисления начинаются с 1, вы можете просто использовать это вместо:
public static Day forInt(int id) {
return values()[id - 1];
}
Ответ 3
Класс перечисления должен иметь карту поиска, встроенную внутри как статическую переменную. Следовательно, ваш класс enum должен быть чем-то вроде.
public static enum Day {
SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);
public final int fId;
private Day(int id) {
this.fId = id;
}
private static final Map<Integer, Day > lookup
= new HashMap<Integer, Day >();
static {
for (Day s : EnumSet.allOf(Day.class))
lookup.put(s.getIntValue(), s);
}
public static Day getValue(int intValue) {
return lookup.get(intValue);
}
}
Затем, чтобы получить правильное перечисление на основе int i, вы можете просто вызвать
Day.getValue(i);
Этот подход будет работать, даже если нумерация нелинейна или имеет пробелы.
Ответ 4
Отредактированный - кэш создан ленивым.
Вы можете создать рабочую среду Map<Integer,Day>
и использовать ее в реализации getDay.
public static enum Day {
SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);
private static Map<Integer,Day> CACHE = null;
private static void lazyFillCache() {
if (CACHE != null) return;
final Map<Integer,Day> c = new HashMap<Integer,Day>();
for (final Day d : Day.values()) {
c.put(d.fId, d);
}
CACHE = c;
}
public static Day getDay(int i) {
lazyFillCache();
return CACHE.get(i);
}
public final int fId;
private Day(int id) {
this.fId = id;
}
}
Изменить -
Вдохновленный комментатором Tom Hawtins здесь, вы также можете использовать эту реализацию, которая использует возможности загрузки классов Java:
public static enum Day {
SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THURSDAY(5), FRIDAY(6), SATURDAY(7);
private static class Cache {
private static Map<Integer,Day> CACHE = new HashMap<Integer,Day>();
static {
for (final Day d : Day.values()) {
CACHE.put(d.fId, d);
}
}
}
public static Day getDay(int i) {
return Cache.CACHE.get(i);
}
public final int fId;
private Day(int id) {
this.fId = id;
}
}
Ответ 5
Day.values () вернет массив с нулевым значением значений перечисления.
Ответ 6
Day myDay = Day.values () [x] - x - значение int