Как передать значение из одного перечисления в другое в 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 различные типы ничего общего.


вы можете определить метод в 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);

        }*