Подтвердить что ты не робот

Как использовать перечисление с группировкой и иерархией подгрупп/вложением

У меня есть один enum 'класс', называемый Example следующим образом:

enum Example {
//enums belonging to group A:
   enumA1,
   enumA2,
   enumA3,
//enums belonging to group B:
   enumB1,
   enumB2,
   enumB3,
//enums belonging to group C:
   enumC1,
   enumC2,
   enumC3;
}

Для моего проекта важно, чтобы все перечисления, с которыми я работаю, принадлежат Example (так как это аргумент в конструкторе класса).

Как использовать иерархию/вложенность enum для достижения следующего:

  • Метод, который проверяет, является ли enum группой A, B или C. Например, что-то вроде Example.enumA1.isGroupBelonging(Group.A) или isGroupBelonging(Example.enumA1,Group.A) будет публичным методом, который возвращает true.

  • Уметь делать то же самое с подгруппами группы A, B и C. Например, группа А может иметь подгруппы A, B и C. Затем мне нужен метод, который делает что-то вроде Example.enumA1.isSubGroupBelonging(SubGroup.a), который является public boolean.

  • Способ сделать все это без необходимости иметь сложное имя enum, которое забивает мой код. Например, было бы неплохо просто иметь возможность ссылаться на Example.enumA1 на всех моих других классах, не обращаясь к нему, используя что-то вроде Example.enumA1(Group.A,SubGroup.a) или Example.enumA1.Group.A.SubGroup.a

4b9b3361

Ответ 1

Я бы использовал очень простой конструктор enum, который связывает соответствующую группу с значением перечисления:

public enum Example {

    ENUM_A1 (Group.A),
    ENUM_A2 (Group.A),
    ENUM_A3 (Group.A),

    ENUM_B1 (Group.B),
    ENUM_B2 (Group.B),
    ENUM_B3 (Group.B),

    ENUM_C1 (Group.C),
    ENUM_C2 (Group.C),
    ENUM_C3 (Group.C);

    private Group group;

    Example(Group group) {
        this.group = group;
    }

    public boolean isInGroup(Group group) {
        return this.group == group;
    }

    public enum Group {
        A,
        B,
        C;
    }
}

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

import static Example.*;
import Example.Group;
...

ENUM_A1.isInGroup(Group.A);  // true
ENUM_A1.isInGroup(Group.B);  // false

Чтобы сделать подгруппы, вы можете сделать аналогичную структуру для группы как для примера, используя Group(SubGroup ... subgroups) в качестве конструктора и EnumSet<SubGroup>, чтобы содержать подгруппы.

Ответ 2

Вы можете использовать EnumSet для группировки различных перечислений без создания отдельного класса Enum:

public enum Example {

    ENUM_A1, ENUM_A2, ENUM_A3,
    ENUM_B1, ENUM_B2, ENUM_B3,
    ENUM_C1, ENUM_C2, ENUM_C3;

    public static EnumSet<Example> groupA = EnumSet.of(ENUM_A1, ENUM_A2, ENUM_A3);
    public static EnumSet<Example> groupB = EnumSet.of(ENUM_B1, ENUM_B2, ENUM_B3);
    public static EnumSet<Example> groupC = EnumSet.of(ENUM_C1, ENUM_C2, ENUM_C3);

}   

public static void main(String[] args){
    if(Example.groupA.contains(Example.ENUM_A1)){
       System.out.println("Group A contains ENUM A1");
    }
}

Ответ 3

Небольшое дополнение:

Мне нравятся оба ответа от @ELEVATE и @Wendel. И это зависит (как всегда) от сценария, когда использовать какое решение. Если каждая запись должна быть частью одной группы, я предпочитаю решение ELEVATE, потому что это заставляет меня добавлять эту отдельную группу. Однако, если нужно перечислить только некоторые перечисления или они не отличаются друг от друга, я согласен с решением Wendel, потому что он более гибкий (но более подверженный ошибкам)