Вместо повторения кода в каждом enum
вы можете реализовать центральный метод утилиты для всех видов перечислений с значением int
. Это возможно, поскольку enum
s может реализовывать интерфейсы, следовательно, вы можете определить единый способ доступа к значению int
:
public interface IntValued {
int intValue();
}
/** get the particular {@link IntValued} {@code enum} constant. */
public static <T extends Enum<T>&IntValued> T get(Class<T> type, int value) {
return type.cast(GET.get(type).apply(value));
}
private static ClassValue<IntFunction<Enum>> GET = new ClassValue<IntFunction<Enum>>() {
protected IntFunction<Enum> computeValue(Class<?> type) {
return prepare(type);
}
};
// invoked only once per enum type
static IntFunction<Enum> prepare(Class<?> type) {
Enum[] values=type.asSubclass(Enum.class).getEnumConstants();
if(values.length==0) return i -> null;
IntSummaryStatistics s=Arrays.stream(values)
.mapToInt(o -> ((IntValued)o).intValue())
.summaryStatistics();
int min=s.getMin(), max=s.getMax();
if((max-min+1)<s.getCount()*2) {
Enum[] linear=new Enum[max-min+1];
for(Enum e: values) linear[((IntValued)e).intValue()-min]=e;
return i -> i<min||i>max? null: linear[i-min];
}
Map<Integer, Enum> map = Arrays.stream(values).collect(
Collectors.toMap(o -> ((IntValued)o).intValue(), Function.identity()));
return map::get;
}
Это использует ClassValue
, JRE при условии способа ассоциирования пользовательских метаданных к классу. ClassValue
заботится о том, чтобы вызвать код инициализации только один раз и до сих пор позволяет выгрузку мусора/разгрузку класса. Приведенный выше код динамически определяет, какую структуру поиска использовать. Если значения int
конкретного типа enum
плотны, он использует массив, в противном случае он обращается к Map
.
Вы можете использовать его следующим образом:
public enum Color implements IntValued {
RED(10),
GREEN(22),
BLUE(33);
private int value;
Color(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}
Color color=get(Color.class, 22);
System.out.println(color);
Обратите внимание, что это решение, в отличие от сгенерированных switch
заявлений, не сломаться, если эти ИНТ значения изменяются.
Сколько таких 'enum' вы ожидаете написать в своей жизни? – Holger
Я работаю над проектом, в котором много перечислений должны быть введены с более чем тремя значениями внутри. Его в реальном времени тратить, чтобы закодировать все это вручную. – George
Для любви к Богу используйте универсальные цветовые коды. Это сделает вашу жизнь, а также разработчиков, которые придут после вас, немного легче. таким образом, вы не имеете дело с этим перечислением. –