Как использовать перечисление с группировкой и иерархией подгрупп/вложением
У меня есть один 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
Ответы
Ответ 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, потому что он более гибкий (но более подверженный ошибкам)