实现相同接口的枚举上的Java切换

我有一个小组项目,我们被迫使用提供的接口和枚举。

想象一下如下情况:

// marker interface interface Request{} // marker interface interface Response{} enum TypeAction implements Request{ TYPE1, TYPE2, TYPE3 } enum OtherTypeAction implements Request{ OTHERTYPE1, OTHERTYPE2 } 

在另一个类中,我有一个请求列表,如下所示: List req = new LinkedList()我想做的是:做一个如下所示的开关:

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

我怎么能设法做到这一点?

重要说明:我无法在接口和枚举中添加方法,但我可以创建实现上面可以看到的接口的新枚举。 如果可能的话,我宁愿没有两个能做同样事情的枚举。

编辑:它与可能的重复答案不同,因为我无法在Request接口中添加任何方法,因此我无法在枚举类中实现方法。

提前致谢

你提到的开关显然不起作用。

我有一个(非常奇怪的)替换:创建一个“helper enum”,其中包含列出的所有值,并且有一个Map>, HelperEnum> ,如下所示:

 private enum HelperEnum { TYPE1(TypeAction.TYPE1), TYPE2(TypeAction.TYPE2), TYPE3(TypeAction.TYPE3), OTHERTYPE1(OtherTypeAction.OTHERTYPE1), OTHERTYPE2(OtherTypeAction.OTHERTYPE2), private Request source; private HelperEnum(Request source) { this.source = source; } private static Map, HelperEnum> map; public static HelperEnum lookUp(Request source) { if (map == null) { map = Arrays.stream(HelperEnum.values()) .collect(Collectors.toMap(x -> x.source, x -> x)); } return map.get(source); } 

(未经测试!特别是我使用Request可能是错误的;我必须先测试它们。但你应该明白这一点。)

这样你就可以做到

 switch(HelperEnum.lookUp(a_request)){ case TYPE1: .... case TYPE2: .... case TYPE3: .... case OTHERTYPE1: .... case OTHERTYPE2: .... } 

您可以使用地图而不是开关:

 interface MyRequestTypeAction{ void doSomething(); } Map 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(); 

如果您有行为,例如Request可以触发多个枚举操作,或者单个操作的实现与其他操作有很大不同,那么您需要一个更灵活的解决方案,您可以采用这种方式:

 public enum RequestHandlers { TYPE1_HANDLER(TypeAction.TYPE1::equals, Request::methodA), TYPE2_HANDLER(r -> r == TypeAction.TYPE2), OTHERTYPE1_HANDLER(OtherTypeAction.OTHERTYPE1::equals), COMMON_HANDLER(x -> true, MyLogger::trace); private final Predicate> requestFilter; // selects supported requests for this handler private final Consumer> consumer; // implements this handler's behaviour private RequestHandlers(Predicate> p, Consumer> consumer) { this.requestFilter = p; this.consumer = consumer; } private RequestHandlers(Predicate> p) { this.requestFilter = p; this.consumer = Request::methodB; // default behaviour for all handlers } public static void handle(Request... requests) { Arrays.stream(RequestHandlers.values()) .forEach(handler -> Arrays.stream(requests) .filter(handler.requestFilter) .forEach(request -> handler.consumer.accept(request))); } } 

请注意,当操作符合给定请求时,条件可通过filterPredicateConsumer的操作进行配置。

不幸的是,您不能将switch用于实际代码,但可以使用if语句执行此操作:

 final List req = new LinkedList<>(); for (Request request : req) { if (TypeAction.TYPE1.equals(request)) { //code } else if (OtherTypeAction.OTHERTYPE1.equals(request)) { //code } } 

也许你可以添加更多的字段来请求和枚举,然后你可以等于这个字段。