it-swarm.com.de

Verwendung von Enum mit Gruppierung und Untergruppierungshierarchie/Verschachtelung

Ich habe eine enum'class' namens Examplewie folgt:

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;
}

Es ist wichtig für mein Projekt, dass alle Enumerationen, mit denen ich arbeite, zu Examplegehören (da dies ein Argument in einem Konstruktor einer Klasse ist). 

Wie verwende ich enumHierarchie/Verschachtelung, um Folgendes zu erreichen:

  • Eine Methode, die testet, ob ein enumaus der Gruppe A, B oder C besteht. Etwas wie Example.enumA1.isGroupBelonging(Group.A) oder isGroupBelonging(Example.enumA1,Group.A) wäre zum Beispiel eine öffentliche Methode, die true zurückgibt.

  • Dasselbe können Sie mit Untergruppen der Gruppe Aname__, Bund Cmachen. Gruppe A kann beispielsweise die Untergruppen aname__, bund chaben. Ich möchte dann eine Methode, die etwas tut, wie zum Beispiel Example.enumA1.isSubGroupBelonging(SubGroup.a), was ein public boolean ist.

  • Eine Möglichkeit, dies alles zu tun, ohne einen ausgefeilten enumNamen zu benötigen, der meinen Code verstopft. Zum Beispiel wäre es schön, wenn ich in allen anderen Klassen einfach auf Example.enumA1 verweisen könnte, ohne auf etwas wie Example.enumA1(Group.A,SubGroup.a) oder Example.enumA1.Group.A.SubGroup.a verweisen zu müssen.

19
user2763361

Ich würde einen sehr einfachen Enum-Konstruktor verwenden, der die entsprechende Gruppe mit dem Enumerationswert verknüpft:

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;
    }
}

Verwendungszweck:

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

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

Um die Untergruppen zu erstellen, können Sie für Group eine ähnliche Struktur wie für Beispiel erstellen, indem Sie Group(SubGroup ... subgroups) als Konstruktor und EnumSet<SubGroup> die Untergruppen enthalten.

39

Sie können EnumSet verwenden, um verschiedene Enums zu gruppieren, ohne eine separate Enum -Klasse zu erstellen:

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");
    }
}
26
Wendel

Kleiner Zusatz:

Ich mag beide Antworten von @ELEVATE und @Wendel. Und es hängt (wie immer) vom Szenario ab, wann welche Lösung verwendet werden soll. Wenn jeder Eintrag Teil einer einzelnen Gruppe sein muss, bevorzuge ich die Lösung von ELEVATE, da ich dazu gezwungen bin, diese einzelne Gruppe hinzuzufügen. Wenn jedoch nur einige Enummen gruppiert werden müssen oder sie nicht eindeutig sind, gehe ich mit der Lösung von Wendel, weil sie flexibler (aber fehleranfälliger) ist.

0
Christian Lutz