3

I have these two Enums declared as such:

public enum EnumOne implements EnumInterface {
    SomethingHere,
    SomethingThere;
    public void someMethod () { }
}

public enum EnumTwo implements EnumInterface {
    SomethingOverYonder;
    public void someMethod () { }
}

As seen here, they both implement this Interface.

public Interface EnumInterface {
     someMethod();
}

I have a class defined here that contains an EnumSet that will get all the elements from either Enum1 or Enum2. That will be defined via a method that has an index as a parameter. Something like this:

public class SomeClass {
    private EnumSet someEnum;
    public void setEnumType (int index) {
        switch (index) {
        case 1:
            someEnum = EnumSet.allOf(EnumOne.class);
            break;
        case 2:
            someEnum = EnumTwo.allOf(EnumTwo.class);
            break;
        }
    }
}

Now, I know I have to use generics to accomplish this somehow, but i don't know how to do it exactly since I'm not familiar enough with it and I'm hoping you can enlighten me a bit.

Thanks in advance for your answers.

ShadowGeist
  • 71
  • 1
  • 3
  • 9
  • Btw enum cannot be used as a variable name. – Mordechai Oct 05 '16 at 03:00
  • @MouseEvent Thanks for the note, I'll edit that out, although the idea of what I want to do still comes across just fine i think. – ShadowGeist Oct 05 '16 at 03:13
  • If later you want to use EnumSet specific methods, it will not work as you cannot have proper type parameter for your `someEnum` declaration. If you are merely using it as a `Set`, then simply `Set someEnum = new HashMap<>(EnumSet.allOf(EnumOne.class));`. However, I feel it is fundamentally wrong in design... You may want to tell us why you want to do something like this – Adrian Shum Oct 05 '16 at 03:30
  • @AdrinShum I'm currently working on a project that consists on selling diferent types of furniture to a customer. The customer needs to specify what kind of wood he wants the furniture to be made of. I've created enums for both finger-jointed wood and melamine wood so far. Each one of these types of wood have specifications that are exclusive to them, so they need to be defined separately. Basically, I want the customer to be able to choose the type of wood he wants and for that I need to use work with the enumerator that belongs to the type of wood he chooses. – ShadowGeist Oct 05 '16 at 04:45
  • @AdrianShum You probably mean `HashSet` right? – Mordechai Oct 05 '16 at 18:07
  • I feel using enum for such purpose may not be a wise choice. Wood types are not that static; you don't really need compile time checking for this (at least based on your example and the supplied answer ) – Adrian Shum Oct 06 '16 at 00:21
  • @MouseEvent ya. Just typo :P – Adrian Shum Oct 06 '16 at 00:22
  • What is your question? What do you want changed from the code you have shown? – newacct Oct 06 '16 at 00:39

2 Answers2

1

It is unclear what you are looking for, but if you just want someEnum to not be declared with a raw type, this works:

public class SomeClass {
    private EnumSet<? extends EnumInterface> someEnum;
    public void setEnumType (int index) {
        switch (index) {
        case 1:
            someEnum = EnumSet.allOf(EnumOne.class);
            break;
        case 2:
            someEnum = EnumSet.allOf(EnumTwo.class);
            break;
        }
    }
}
newacct
  • 119,665
  • 29
  • 163
  • 224
  • I want the EnumSet to assume all the values of one Enum or the other depending on what the user requires. I stated in a previous comment that the project I'm working on consists on selling the user different types of furniture. The furniture is made of either melamine or finger-jointed wood. The user decides what kind of wood the furniture is made of. These two enums are for describing these two types of wood. – ShadowGeist Oct 06 '16 at 00:54
0

This is how I did it:

public class SomeClass {                                                                                                                                                  

    private EnumSet<? extends EnumInterface> someEnum;                                                                                                                    

    // I control it, so it's checked                                                                                                                                      
    @SuppressWarnings("unchecked")                                                                                                                                        
    public <E extends Enum<E> & EnumInterface> void setEnumType(int index) {                                                                                              
        switch (index) {                                                                                                                                                  
        case 1:                                                                                                                                                           
            someEnum = (EnumSet<E>) EnumSet.allOf(Enum1.class);                                                                                                           
            break;                                                                                                                                                        
        case 2:                                                                                                                                                           
            someEnum = (EnumSet<E>) EnumSet.allOf(Enum2.class);                                                                                                           
            break;                                                                                                                                                        
        default:                                                                                                                                                          
        }                                                                                                                                                                 

    }  


    public EnumSet<? extends EnumInterface> getEnum() {                                                                                                                   
        return someEnum;                                                                                                                                                  
    }     

}

Testing:

public static void main(String[] args) {                                                                                                                              
    SomeClass c = new SomeClass();                                                                                                                                    
    c.setEnumType(2);                                                                                                                                                 
    EnumSet<? extends EnumInterface> e = c.getEnum();                                                                                                                 
    System.out.println(e);                                                                                                                                            

    for (EnumInterface ei : e)                                                                                                                                        
        ei.someMethod();                                                                                                                                              

    }                                                                                                                                                                     

} 
Mordechai
  • 15,437
  • 2
  • 41
  • 82
  • Hmmm, this seems to accomplish what I want to do. Just one question. What kind of warning is being thrown by the compiler there and why are you suppressing it? Nothing to be worried about, right? Excuse my ignorance, It's the first time I see one of those. – ShadowGeist Oct 05 '16 at 18:23
  • Unchecked generic type cast. – Mordechai Oct 05 '16 at 18:50
  • 1
    It doesn't make any sense to have a generic method where the type parameter is not used in the parameter or return types. – newacct Oct 06 '16 at 00:30
  • And the use of the generics is wrong here, because what a type parameter means is that your code would be correct for any arbitrary choice of `E` that satisfies the bounds, including, but here it obviously isn't, because neither `EnumSet` nor `EnumSet` is a subtype of `EnumSet` – newacct Oct 06 '16 at 00:33