Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java switch on enum that implements same interface

I have a group project where we are forced to use interfaces and enumerations provided.

Imagine a situation like below :

// marker interface
interface Request<T extends Response>{}

// marker interface
interface Response{}

enum TypeAction implements Request<SomeEnumClassThatImplementsResponse>{
      TYPE1, TYPE2, TYPE3
}

enum OtherTypeAction implements Request<SomeOtherEnumClassThatImplementsResponse>{
      OTHERTYPE1, OTHERTYPE2    
}

In an other class, I have a List of Request like this : List<Request> req = new LinkedList<Request>() What I want to do is : make a switch like below :

switch(a_request){
   CASE TYPE1: ....
   CASE TYPE2: ....
   CASE TYPE3: ....
   CASE TYPE2: ....
   CASE OTHERTYPE1: ....
   CASE OTHERTYPE2: ....
}

How can I manage to do this please ?

IMPORTANT NOTE : I can't add methods into the interfaces and into the enums but I can create new enums that implements the interfaces you can see above. I'd rather not have two enums that do the same thing if possible.

EDIT : It's different to the possible duplicate answer in that I can't add any method in the Request interface and so I can't implement a method in the enum classes.

Thanks in advance

like image 729
Meyer Cohen Avatar asked Jan 27 '17 09:01

Meyer Cohen


People also ask

Can a Java enum implement an interface?

Yes, Enum implements an interface in Java, it can be useful when we need to implement some business logic that is tightly coupled with a discriminatory property of a given object or class.

Can you switch on enum Java?

You definitely can switch on enums.

Can you use a switch statement for enums?

We can use also use Enum keyword with Switch statement. We can use Enum in Switch case statement in Java like int primitive.

Can enum inherit interface?

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


2 Answers

The switch you mention does obviously not work.

I have a (quite weird) substitution: create a "helper enum" which contains all values listed, and have a Map<Request<Request<T extends Response>>, HelperEnum>, like this:

private enum HelperEnum {
       TYPE1(TypeAction.TYPE1),
       TYPE2(TypeAction.TYPE2),
       TYPE3(TypeAction.TYPE3),
       OTHERTYPE1(OtherTypeAction.OTHERTYPE1),
       OTHERTYPE2(OtherTypeAction.OTHERTYPE2),

       private Request<T extends Response> source;

       private HelperEnum(Request<T extends Response> source) {
           this.source = source;
       }

       private static Map<Request<T extends Response>, HelperEnum> map;

       public static HelperEnum lookUp(Request<SomeEnumClassThatImplementsResponse> source) {
           if (map == null) {
               map = Arrays.stream(HelperEnum.values())
                   .collect(Collectors.toMap(x -> x.source, x -> x));
           }
           return map.get(source);
       }

(untested! Especially the places where I use Request<T extends Response> might be wrong; I'd have to test them first. But you should get the idea.)

This way you can then do

switch(HelperEnum.lookUp(a_request)){
    case TYPE1: ....
    case TYPE2: ....
    case TYPE3: ....
    case OTHERTYPE1: ....
    case OTHERTYPE2: ....
}
like image 106
glglgl Avatar answered Nov 14 '22 22:11

glglgl


You could use a map instead of a switch:

interface MyRequestTypeAction{
  void doSomething();
}

Map<Request, MyRequestTypeAction> requestActions = new HashMap<>(){{
   put(TypeAction.TYPE1,()->System.out.printLine("TypeAction.TYPE1"));
   put(TypeAction.TYPE2,()->System.out.printLine("TypeAction.TYPE2"));
   put(TypeAction.TYPE3,()->System.out.printLine("TypeAction.TYPE3"));
   put(OtherTypeAction.OTHERTYPE1,()->System.out.printLine("OtherTypeAction.OTHERTYPE1"));
   put(OtherTypeAction.OTHERTYPE2,()->System.out.printLine("OtherTypeAction.OTHERTYPE2"));
}}

requestActions.get(a_request).doSomething();
like image 30
Timothy Truckle Avatar answered Nov 14 '22 21:11

Timothy Truckle