Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use enum with grouping and subgrouping hierarchy/nesting

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

like image 491
user2763361 Avatar asked Oct 30 '13 11:10

user2763361


People also ask

Can enums have hierarchy?

Although we are regular to use enums as some kind of static arrays they also can be used to present hierarchical tree-like data structures where each node can find its parent, its children and even inherit and override parent's method almost exactly as we do with class inheritance.

Can enums be nested?

Your example shows just two enums. Tea is an enumeration and Coffies is an enumeration. But Drink is no enumeration. Nesting of enums means that Drinks itself should be no interface but an enumeration of Coffee and Tea.

How do you define an enum with multiple values?

we should do the following steps to have an enum with different values: Create enum constructor which accepts multiple values. Assign each constructor argument to a member field in the enum definition. Create getter methods so we can access any of the values assigned to a particular enum constant.

Can you nest enums in Java?

Department enum defined above is a nested enum type as it is 'nested' inside another class. Nested enum types are implicitly static, and hence mentioning static in their definition is actually redundant. An enum constant of static nested enum Department type can be accessed using the syntax – <enclosing-class-name>.


2 Answers

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.

like image 85
ᴇʟᴇvᴀтᴇ Avatar answered Sep 30 '22 05:09

ᴇʟᴇvᴀтᴇ


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");
    }
}
like image 44
Wendel Avatar answered Sep 30 '22 03:09

Wendel