簡體   English   中英

實現相同接口的枚舉上的Java切換

[英]Java switch on enum that implements same interface

我有一個小組項目,我們被迫使用提供的接口和枚舉。

想象一下如下情況:

// 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    
}

在另一個類中,我有一個請求列表,如下所示: List<Request> req = new LinkedList<Request>()我想做的是:做一個如下所示的開關:

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

我怎么能設法做到這一點?

重要說明:我無法在接口和枚舉中添加方法,但我可以創建實現上面可以看到的接口的新枚舉。 如果可能的話,我寧願沒有兩個能做同樣事情的枚舉。

編輯:它與可能的重復答案不同,因為我無法在Request接口中添加任何方法,因此我無法在枚舉類中實現方法。

提前致謝

你提到的開關顯然不起作用。

我有一個(非常奇怪的)替換:創建一個“helper enum”,它包含列出的所有值,並且有一個Map<Request<Request<T extends Response>>, HelperEnum> ,如下所示:

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);
       }

(未經測試!特別是我使用Request<T extends Response>可能是錯誤的;我必須先測試它們。但你應該明白這一點。)

這樣你就可以做到

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

您可以使用地圖而不是開關:

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();

不幸的是,您不能將switch用於實際代碼,但您可以使用if語句執行此操作:

final List<Request> req = new LinkedList<>();

for (Request request : req) {
    if (TypeAction.TYPE1.equals(request)) {
        //code
    }
    else if (OtherTypeAction.OTHERTYPE1.equals(request)) {
        //code
    }
}

也許你可以添加更多的字段來請求和枚舉,然后你可以等於這個字段。

如果您有行為,例如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<Request<?>> requestFilter; // selects supported requests for this handler

    private final Consumer<Request<?>> consumer; // implements this handler's behaviour

    private RequestHandlers(Predicate<Request<?>> p, Consumer<Request<?>> consumer) {
        this.requestFilter = p;
        this.consumer = consumer;
    }

    private RequestHandlers(Predicate<Request<?>> 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)));
    }
}

請注意,當操作符合給定請求時,條件可通過過濾器PredicateConsumer的操作進行配置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM