Как передать значение из одного перечисления в другое в Java?
Как я могу привести значение из Enum1 в Enum 2 в Java? Вот пример того, что я пытаюсь сделать :
public enum Enum1 {
ONE,
TWO,
THREE;
}
public enum Enum2 {
FOUR,
FIVE,
SIX;
}
поэтому я хочу сделать что-то вроде этого:
Enum2 en2 = (Enum2)ONE;
возможно ли это и как я могу это сделать?
спасибо заранее!
11 ответов
вы не можете переходить от одного перечисления к другому, однако каждое перечисление имеет гарантированный порядок, и вы можете легко перевести одно перечисление в другое (сохраняя порядок). Например:
enum E1 {
ONE, TWO, THREE,
}
enum E2 {
ALPHA, BETA, GAMMA,
}
мы можем перевести E1.TWO
to / from E2.BETA
by:
static E2 E1toE2(E1 value) {
return E2.values()[value.ordinal()];
}
static E1 E2toE1(E2 value) {
return E1.values()[value.ordinal()];
}
вы можете определить метод в Enum1, чтобы вернуть соответствующий Enum2:
enum Enum1 {
ONE {
@Override
public Enum2 toEnum2() {
return Enum2.ALFA;
}
},
TWO {
@Override
public Enum2 toEnum2() {
return Enum2.BETA;
}
}
,
THREE {
@Override
public Enum2 toEnum2() {
return Enum2.GAMMA;
}
}
;
public abstract Enum2 toEnum2();
}
enum Enum2 {
ALFA, BETA, GAMMA;
}
или, немного более читаемый (IMO):
enum Enum1 {
ONE(Enum2.ALFA),
TWO(Enum2.BETA),
THREE(Enum2.GAMMA);
private final Enum2 enum2;
private Enum1(Enum2 enum2) {
this.enum2 = enum2;
}
public Enum2 toEnum2() {
return enum2;
}
}
enum Enum2 {
ALFA, BETA, GAMMA;
}
EDIT:
если вам нужно сохранить 2 перечисления, разделенных, создайте карту, содержащую отображение из Enum1 в Enum2 (в 3-м классе утилиты).
ответ на этот вопрос может зависеть от того, что "кастинг" требуется:
кастинг по порядковому положению
в приведенном примере нет общности между наборами значений в двух перечислениях, поэтому я предполагаю, что намерение состояло в том, чтобы перевести порядковое положение так, что Enum1.ONE
=>Enum2.FOUR
, Enum1.TWO
=>Enum2.FIVE
и Enum1.THREE
=>Enum2.SIX
. Это можно сделать следующим образом:
Enum2 en2 = Enum2.values()[Enum1.ONE.ordinal()];
следующий естественный вопрос-как это может быть расширена до универсальной функции, которая будет делать то же самое для любых двух enum
типы. Не для слабонервных, но следующее сделает работу (она требует гуавы):
public <F extends Enum<F>> F castByOrdinal(Enum<?> e, Class<F> fClass) {
return Iterators.get(EnumSet.allOf(fClass).iterator(), e.ordinal());
}
если библиотека Google Guava отсутствует, это можно сделать вручную в нескольких строках кода:
public <F extends Enum<F>> F castByOrdinal(final Enum<?> e, final Class<F> fClass) {
final Iterator<F> iter = EnumSet.allOf(fClass).iterator();
int count = 0;
F fValue = null;
while (count <= e.ordinal()) {
if (!iter.hasNext()) {
return null; // Or throw exception if preferred e.g. IndexOutOfBoundsException
}
fValue = iter.next();
count++;
}
return fValue;
}
пример использования:
Enum2 en2 = castByOrdinal(Enum1.ONE, Enum2.class);
кастинг по общим именам значений перечисления
существует еще один возможный способ литья между перечислениями которые имеют одни и те же имена значений:
например:
enum Shape {
TRIANGLE, SQUARE, PENTAGON, HEXAGON, UNKNOWN, NOT_APPLICABLE
}
enum Size {
SMALL, MEDIUM, LARGE, UNKNOWN, NOT_APPLICABLE
}
это литье будет работать только для общих значений (т. е. UNKNOWN
и NOT_APPLICABLE
выше) и может быть сделано следующим образом:
Size size = Size.valueOf(Shape.UNKNOWN.name());
это вызовет исключение IllegalArgumentException, если имя значения не существует в целевом перечислении. На этот раз общий метод может быть немного проще:
public <F extends Enum<F>> F castByName(final Enum<?> e, final Class<F> fClass) {
return F.valueOf(fClass, e.name());
}
пример использования:
Size size = castByName(Shape.UNKNOWN, Size.class);
вы не можете этого сделать, потому что они объекты разных классов.
вы можете преобразование от одного к другому на основе порядкового значения или имени, но я бы поставил под сомнение дизайн любой программы, которая должна была это сделать.
вы не можете ; но вы можете создать статический метод в своих перечислениях с кодом перевода. Но у вас должно быть четкое представление о правилах, которые вы хотите реализовать.
хотя этот билет был активен довольно давно, я добавляю еще одну возможность:
вы также можете создать карту, например, такой:
HashMap<Enum1, Enum2> e1ToE2 = new HashMap<Enum1, Enum2>();
e1ToE2.put(Enum1.ONE, Enum2.FOUR);
e1ToE2.put(Enum1.TWO, Enum2.FIVE);
использование
Enum2 e2 = e1ToE2.get(Enum1.ONE);
(+) вам не нужно дважды проверять порядок ваших элементов
(+) легко читать
(+) быстро
(-) требует пространства
поправьте меня, если я ошибаюсь :)
операция приведения невозможна, но вы можете написать статическую функцию-член для enum1, которая приводит enum2 к enum1:
public static Enum1 fromEnum2(Enum2 enum2) {
...
}
кстати, вы можете назначить идентификатор каждой константе обоих перечислений, что упрощает реализацию.
здесь это учебник по перечислениям.
Это, вероятно, не поможет вам, но вы можете иметь
public enum Enum1 implements MyInterface {...}
public enum Enum2 implements MyInterface {...}
у нас не хватает информации о том, что вы пытаетесь сделать, чтобы помочь вам. Нет смысла как бросить перечислимый в другое перечисление.
вы не можете бросить из одного перечисления в другое, однако каждое перечисление имеет гарантированный порядок, и вы можете легко перевести одно перечисление в другое
вы можете сделать это, используя простой способ:
public enum number{one,two};
public enum number1{one,two};
public void castTonumber1(number number){
number1 num1 = number1.valueOf(number.one.toString());
System.out.println( "value of number 1 is " + num1);
}*