web-dev-qa-db-fra.com

Comment utiliser enum avec le regroupement et la hiérarchie/imbrication de sous-groupes

J'ai une enum 'classe' appelée Example comme suit:

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

Il est important pour mon projet que tous les enums avec lesquels je travaille appartiennent à Example (puisqu'il s'agit d'un argument dans un constructeur de classe). 

Comment utiliser la hiérarchie/imbrication enum pour obtenir les résultats suivants:

  • Une méthode qui teste si une enum appartient aux groupes A, B ou C. Par exemple, quelque chose comme Example.enumA1.isGroupBelonging(Group.A) ou isGroupBelonging(Example.enumA1,Group.A) serait une méthode publique qui renvoie true.

  • Pouvoir faire la même chose avec les sous-groupes du groupe A, B et C. Par exemple, le groupe A peut avoir des sous-groupes a, b et c. Je veux alors une méthode qui fait quelque chose comme Example.enumA1.isSubGroupBelonging(SubGroup.a) qui est un public boolean.

  • Une façon de faire tout cela sans avoir besoin d'un nom enum élaboré qui obstrue mon code. Par exemple, il serait agréable de pouvoir simplement faire référence à Example.enumA1 dans mes autres classes sans avoir besoin de s'y référer en utilisant quelque chose comme Example.enumA1(Group.A,SubGroup.a) ou Example.enumA1.Group.A.SubGroup.a

19
user2763361

J'utiliserais un constructeur enum très simple qui associe le groupe correspondant à la valeur 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;
    }
}

Usage:

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

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

Pour faire les sous-groupes, vous pouvez créer un type de structure similaire pour Group comme pour Example, en utilisant Group(SubGroup ... subgroups) comme constructeur et un EnumSet<SubGroup> pour contenir les sous-groupes.

39
ᴇʟᴇvᴀтᴇ

Vous pouvez utiliser EnumSet pour regrouper différentes énumérations sans créer un Enum class séparé:

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

Petit ajout:

J'aime les deux réponses de @ELEVATE et @Wendel. Et cela dépend (comme toujours) du scénario dans lequel utiliser quelle solution . Si chaque entrée doit faire partie d'un groupe unique, je préfère la solution d'ELEVATE, car elle m'oblige à ajouter ce groupe unique. Cependant, s'il ne faut grouper que certaines énumérations ou si elles ne sont pas distinctes, j'y vais avec la solution de Wendel, car elle est plus flexible (mais plus sujette aux erreurs)

0
Christian Lutz