28

I have one enum 'class' called Example as follows:

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

It's important for my project they all enums I work with belong to Example (since this is an argument in a constructor of a class).

How do I use enum hierarchy/nesting in order to achieve the following:

  • A method that tests whether an enum is of group A, B or C. For example, something like Example.enumA1.isGroupBelonging(Group.A) or isGroupBelonging(Example.enumA1,Group.A) would be a public method that returns true.

  • Be able to do the same thing with sub-groups of group A, B and C. For example, group A might have subgroups a, b and c. I then want a method that does something such as Example.enumA1.isSubGroupBelonging(SubGroup.a) which is a public boolean.

  • A way to do all this without needing to have some elaborate enum name that clogs up my code. For example, it would be nice to just be able to refer to Example.enumA1 throughout my other classes without needing to refer to it using something like Example.enumA1(Group.A,SubGroup.a) or Example.enumA1.Group.A.SubGroup.a

ekad
  • 14,436
  • 26
  • 44
  • 46
user2763361
  • 3,789
  • 11
  • 45
  • 81

2 Answers2

51

I would use a very simple enum constructor which associates the corresponding group with the enum value:

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

To do the subgroups you can do a similar kind of structure for Group as for Example, using Group(SubGroup ... subgroups) as a constructor and an EnumSet<SubGroup> to contain the subgroups.

ᴇʟᴇvᴀтᴇ
  • 12,285
  • 4
  • 43
  • 66
36

You can use EnumSet to group various enums without creating a separate Enum class:

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");
    }
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Wendel
  • 2,809
  • 29
  • 28
  • 3
    Also seen [here](http://jaxenter.com/enumset-in-java-regularenumset-vs-jumboenumset-106051.html) – ccDict Feb 17 '15 at 12:19
  • 2
    is there guaranteed order in EnumSet? for example I want enums for groupA in following order ENUM_A3, ENUM_A1, ENUM_A2.. Not sure EnumSet would guarantee me order – Ewoks Apr 12 '16 at 11:30
  • 2
    EnumSet is not garantee the order, but you can use the 'Collections.sort(new ArrayList(Example.groupA))' to order it! – Wendel Apr 12 '16 at 17:59
  • @Wendel That wouldn't do anything, as you wouldn't have access to the list. – shmosel Apr 08 '19 at 21:44