Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: New enum which is subset of an old enum

Tags:

java

enums

In Java, is there any way to define a new enum from an existing enum? I want the following capabilities.

public enum A{1, 2, 3, 4, 5, 6, 7, 8, 9};
public enum B{1, 2, 3, 4};
public enum C{3, 4, 5, 6, 7};

1, 2, 3 and all must be identical, i.e,

A.1 == B.1 = true
B.4 == C.4 = true

A real life example would be DAYS, WEEKDAYS, WEEKENDDAYS, LECTUREDAYS, PARTYDAYS and etc.

like image 496
RoboAlex Avatar asked Oct 19 '14 23:10

RoboAlex


People also ask

Can enum inherit enum Java?

Java Enum and Interface As we have learned, we cannot inherit enum classes in Java. However, enum classes can implement interfaces.

Can enums have subclasses?

We've learned that we can't create a subclass of an existing enum. However, an interface is extensible. Therefore, we can emulate extensible enums by implementing an interface.

Can you index enums?

Yes you can programmatically index an enum, text, or menu ring.

Can Java enum extend another enum?

No, we cannot extend an enum in Java. Java enums can extend java. lang. Enum class implicitly, so enum types cannot extend another class.


3 Answers

You can't extend enums, but judging from your week/weekend days example it seems you may need to think about it a little differently. If we have enum Days{ MON, TUE, WED, THU, FRI, SAT, SUN }, then think about the week/weekend days as follows:

EnumSet<Days> weekDays    = EnumSet.range(Days.MON, Days.FRI);
EnumSet<Days> weekendDays = EnumSet.range(Days.SAT, Days.SUN);
EnumSet<Days> partyDays   = EnumSet.of( Days.TUE, Days.THU );

Natural questions like "are any week days also party days?" could then be expressed as you expect:

!Collections.disjoint(weekDays, partyDays)

Hope this helps.

like image 187
Rinke Avatar answered Sep 21 '22 05:09

Rinke


Enumerated types in Java provide the ability to define additional properties and methods.

public enum DAY_INDICATOR {
  SUNDAY(1,true), MONDAY(2,false), TUESDAY(3,false), WEDNESDAY(4,false), THURSDAY(5,false), FRIDAY(6,false), SATURDAY(7,true)
  private final int dayNumber;
  private final bool weekendDay;
  public DAY_INDICATOR(int dn, bool wd) {
    dayNumber = dn;
    weekendDay = wd;
  }
  public bool isWeekendDay() {
    return weekendDay;
  }
  ... more accoutrements of an enumerated type
}

Now you can extend the underlying type with whatever predicates you need to distinguish members of the set of enumerated values according to your business rules.

like image 26
Bob Dalgleish Avatar answered Sep 19 '22 05:09

Bob Dalgleish


I think your best bet would be to do something like:

public class EnumTest
{
  public enum A {
    X1(1), X2(2), X3(3), X4(4), X5(5), X6(6), X7(7), X8(8), X9(9);

    private final int value;
    public int getValue() { return this.value; }
    A(int value) {
      this.value = value;
    }
  }
  public enum B {
    X1(1), X2(2), X3(3), X4(4);
    private final int value;
    public int getValue() { return this.value; }
    B(int value) {
      this.value = value;
    }
  }
  public enum C {
    X3(3), X4(4), X5(5), X6(6), X7(7);

    private final int value;
    public int getValue() { return this.value; }
    C(int value) {
      this.value = value;
    }
  }

  public static void main()
  {
    A a;
    a = A.X1;
    B b;
    b = B.X1;
    if (b.getValue()==a.getValue()) {
      // do something
    }
  }
}

But, if you do that, you should be careful that you are actually using the type safety of Enums, otherwise why not just store all the values as integers? Something like this, where each Enum value has some other meaning could be useful if you sometimes want to compare between Enums, but usually want to use the type-safety. In your "DAYS, WEEKDAYS, WEEKENDDAYS, LECTUREDAYS" example, I'd make sure the internal value is something strongly typed such as a Java8 java.time.DayOfWeek.

like image 20
korvus Avatar answered Sep 20 '22 05:09

korvus