web-dev-qa-db-ja.com

enumをグループ化およびサブグループ化の階層/ネストで使用する方法

次のように、enumと呼ばれるExampleの1つの「クラス」があります。

_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を返すパブリックメソッドになります。

  • グループAB、およびCのサブグループで同じことを行うことができます。たとえば、グループAには、サブグループabおよびcが含まれる場合があります。次に、_public boolean_であるExample.enumA1.isSubGroupBelonging(SubGroup.a)などの処理を行うメソッドが必要です。

  • コードを詰まらせるような複雑なenum名を必要とせずにこれをすべて行う方法。たとえば、Example.enumA1(Group.A,SubGroup.a)や_Example.enumA1_のようなものを使用して参照する必要なく、他のクラス全体で_Example.enumA1.Group.A.SubGroup.a_を参照できればいいでしょう。

22
user2763361

対応するグループを列挙値に関連付ける非常に単純な列挙コンストラクタを使用します。

_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に対して同様の種類の構造を作成できます。コンストラクターとしてGroup(SubGroup ... subgroups)を使用し、サブグループを含む_EnumSet<SubGroup>_を使用します。

42

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

小さな追加:

@ELEVATEと@Wendelの両方の回答が好きです。そして、それは(いつものように)どのソリューションをいつ使用するかというシナリオに依存します。各エントリを1つのグループの一部にする必要がある場合は、この1つのグループを追加する必要があるため、ELEVATEのソリューションを使用します。ただし、一部の列挙型のみをグループ化する必要がある場合、またはそれらが明確でない場合は、より柔軟なため(ただし、エラーが発生しやすい)、ウェンデルのソリューションを使用します。

2
Christian Lutz