-1

It is my understanding that you cannot nest Enums. I was looking to create an enum for ethnicity data, where there are the categories (White, Black, Asian etc) and subcategories (British, African, Indian etc. so that the value could be called as: Ethnicity.WHITE.BRITISH

As you seemingly can't nest enums my solution so far has been as follows (for conciseness I've omitted exception handling and full implementation for each category):

@Getter @Setter
public class Ethnicity

  Enum ethnicity;
  String category;
  String name;

  @Builder
  public Ethnicity(Enum ethnicity) {
    this.ethnicity = ethnicity;
    category = ethnicity.getDeclaringClass.getSimpleName();
    name = ((CategorisableEnum) ethnicity).getName();

  public interface CategorisableEnum {
    String getName();
  }

  public Enum White implements CategoriseableEnum {
    BRITISH("British"), IRISH("Irish"), OTHER("Other");

    public final String ethnicityName;

    White(String ethnicityName) {
      this.ethnicityName = ethnicityName;
  }

I'm using Lombok for the Getter, Setter and Builder annotations. To then use the ethnicity it would be called as:

Ethnicity ethnicity = Ethnicity.builder().ethnicity(Ethnicity.White.BRITISH).build();

This is the part that especially feels like it's incorrect, however I'm struggling to identify something more appropriate. Is this an appropriate means in which to continue with the implementation, or could you point me in the direction of a more appropriate methodology?

The rationale for wanting to implement this is along the lines of that I would like be able to get a count of the number of people that fall under each category.

This is for a personal project to help learn, the idea being it to be a software to get diversity statistics about a group of people.

  • 1
    [Search for existing Questions](https://duckduckgo.com/?q=java+hierarchy+of+enum+site%3Astackoverflow.com&t=ipad&ia=web) on a hierarchy of enum. – Basil Bourque Sep 28 '22 at 15:07

1 Answers1

1

As mentioned in this answer found by doing the search Basil Bourque suggested, you can nest your enums in an interface. In modern versions of Java, you can seal the interface to make it even more enum-like:

public sealed interface Ethnicity
permits Ethnicity.WHITE, 
        Ethnicity.BLACK, 
        Ethnicity.ASIAN {

    enum WHITE
    implements Ethnicity {
        BRITISH, IRISH, OTHER
    }

    enum BLACK
    implements Ethnicity {
        AFRICAN, CARIBBEAN, OTHER
    }

    enum ASIAN
    implements Ethnicity {
        CHINESE, JAPANESE, KOREAN, INDIAN, OTHER
    }

    public static Stream<Class<? extends Ethnicity>> values() {
        return Arrays.stream(Ethnicity.class.getPermittedSubclasses())
            .map(c -> c.asSubclass(Ethnicity.class));
    }

    public static Stream<Ethnicity> leafValues() {
        return values().flatMap(c -> Arrays.stream(c.getEnumConstants()));
    }
}
VGR
  • 40,506
  • 4
  • 48
  • 63