Как сопоставить перечисление с перечислением с теми же ключами - PullRequest
0 голосов
/ 27 апреля 2020

Как отобразить перечисление в перечисление с помощью тех же клавиш в Java. Например ..

public enum FirstEnum {
 A, B
} 

public enum ScndEnum {
 A, B, C
} 

Я не смог найти хорошее решение

Ответы [ 2 ]

3 голосов
/ 27 апреля 2020

Вы не можете напрямую отобразить один тип перечисления на другой, но вы можете использовать значение name() и отобразить его, используя valueOf(). Оба эти метода поставляются со всеми перечисляемыми классами:

ScndEnum aToA = ScndEnum.valueOf(FirstEnum.A.name());

И если вы хотите сделать этот родовой c:

private static <E extends Enum<E>, F extends Enum<F>> 
    F mapEnum(E enum1, Class<F> enum2Class) {

    return Enum.valueOf(enum2Class, enum1.name());
}

, который вы можете вызвать, используя что-то вроде

ScndEnum b = mapEnum(FirstEnum.B, ScndEnum.class)
2 голосов
/ 29 апреля 2020

tl; dr

Разделение объектов между перечислениями не имеет смысла, учитывая определение перечислений в Java.

Возможно, решением для вас является набор перечислений, таких как Map ( пары ключ-значение ), где тип ключа имеет один класс перечисления и тип значения относится к другому классу перечисления.

Map< Animal , Food > feeding = 
    Map.of
    (
        DOG , MEAT ,
        CAT , MEAT ,
        BIRD , SEED ,
        BAT , FRUIT
    )
;

Перечисление - это тип данных

Перечисление в Java - это класс, для которого экземпляры именуются во время компиляции. автоматически создается во время выполнения и не может быть переназначен. См. Учебник по Oracle.

Примеры:

enum Animal { DOG , CAT , BIRD , BAT ; }

enum Flavor { VANILLA , CHOCOLATE , LAVENDER , LEMON ; }

Каждому имени в перечислении будет присвоен объект, экземпляр класса этого перечисления. В приведенных выше примерах константа DOG содержит объект Animal, а константа LEMON содержит объект Flavor.

Использование перечисления в Java имеет смысл, если у вас есть c коллекция экземпляров, которые известны во время компиляции и неизменны во время выполнения. Это означает, что вы не можете позвонить new Animal() в нашем примере выше. Четыре новых объекта Animal были автоматически созданы и назначены каждому из имен переменных при первой загрузке класса. После загрузки этого класса перечисления больше Animal объектов нельзя ни создавать, ни отбрасывать.

Нет разделения между перечислениями

Так что ваш вопрос на самом деле не имеет смысла, учитывая определение перечисления. Объекты одного перечисления не передаются другому перечислению.

Коллекции

Возможно, вы ищете коллекцию объектов перечисления.

Set

Например, здесь мы используем реализацию Set, которая оптимизирована для хранения перечисляемых объектов: EnumSet.

Set< Animal > furryPets = EnumSet.of( DOG , CAT ) ;
Set< Animal > flyingAnimals = EnumSet.of( BIRD , BAT ) ;
Set< Animal > featheredFlyingAnimals = flyingAnimals.clone().remove( BAT ) ;

Map

Вы упомянули, что хотите двустороннее картирование. Поэтому, возможно, вам понадобится Map для отслеживания одного перечисления в качестве ключа и другого перечисления в качестве значения. Класс EnumMap оптимизирован для случаев, когда ваш ключ является перечислением.

В качестве примера давайте добавим еще одно перечисление.

enum Food { MEAT , SEED , FRUIT ; }

Сопоставьте животное с типом пищи.

Map< Animal , Food > feeding = new EnumMap<>( Animal.class ) ;
feeding.put( DOG , MEAT ) ;
feeding.put( CAT , MEAT ) ;
feeding.put( BIRD , SEED ) ;
feeding.put( BAT , FRUIT ) ;

Извлечение типа пищи для кормления летучих мышей.

Food foodForBats = feeding.get( BAT ) ;

Переменная члена

Перечисление в Java - это особый тип класса, но все еще класс. Таким образом, enum может иметь поля-члены, конструкторы и методы доступа, как обычные Java классы.

Таким образом, мы могли бы связать Animal с его Food таким образом, используя поля-члены, конструкторы и методы доступа.

enum Animal 
{
    DOG( Food.MEAT ) , 
    CAT( Food.MEAT ) , 
    BIRD( Food.SEED ) , 
    BAT( Food.FRUIT ) ;

    // Member fields.
    private Food food ;

    // Constructor.
    private Animal( Food foodArg ) 
    {
        this.food = foodArg ;
    }

    // Accessor "getter" method.
    public Food getFood() { return this.food ; }

}

Как уже упоминалось выше, когда класс Animal загружается, его конструктор вызывается четыре раза, по одному на каждую именованную константу. Указанный объект Food передается в этот конструктор автоматически от вашего имени. Вы можете думать об этой строке DOG( Food.MEAT ) , как о сокращении public static final Animal DOG = new Animal( Food.MEAT) ;.

Использование.

Food foodForBats = Animal.BAT.getFood() ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...