簡體   English   中英

Java 8可選,多個過濾器和多個映射

[英]Java 8 Optional, multiple filter and multiple map

我想使用Java 8,如何在Java 8 Optional中使命令式樣式變為功能樣式?

例如,假設exchange.getIn()。getBody()可能為null或不為null。

String color = null;
if(exchange.getIn().getBody() instanceof Foo) {
    color = "toFoo";
} else if(exchange.getIn().getBody() instanceof Bar){
    color = "toBar";
}

也許像這樣的事情,但我需要它在一個襯里中。

 Optional.ofNullable(exchange.getIn().getBody())
         .filter(body -> body instanceof Foo)
         .map(body ->  "toFoo");

我的問題是地圖已經是String,所以我無法將其設為一個內襯:

 Optional.ofNullable(exchange.getIn().getBody())
         .filter(body -> body instanceof Foo)
         .map(body ->  "toFoo")
         .orElse(exchange.getIn().getBody()) //this part is problem, already String
         .filter(body -> body instanceof Bar)
         .map(body -> "toBar");

您想要做的是模式匹配,這不是Optional目的。 您可以濫用Optional來獲得所需的結果,例如

Object o=exchange.getIn().getBody();
String color=Optional.ofNullable(o).filter(Foo.class::isInstance).map(x->"toFoo")
    .orElseGet(()->Optional.ofNullable(o).filter(Bar.class::isInstance).map(x->"toBar")
    .orElse("fallback"));

但這顯然不是真正的勝利,尤其是當您考慮添加更多案例時會發生什么。

實現目標的一種方法是通過Map關聯謂詞和結果:

Map<Predicate<Object>,String> alternatives=new HashMap<>();
alternatives.put(Bar.class::isInstance, "toBar");
alternatives.put(Foo.class::isInstance, "toFoo");

Object o=exchange.getIn().getBody();
String color=alternatives.entrySet().stream()
    .filter(e->e.getKey().test(o))
    .findAny().map(Map.Entry::getValue).orElse("fallback");

這將執行線性搜索(沒有特定順序,因此謂詞必須是不連續的),這在少數情況下效果很好,您可以添加另一個簡單的情況,例如

alternatives.put(Baz.class::isInstance, "toBaz");

但對於大量情況,最好以允許高效查找的方式對謂詞進行編碼(例如,使用類作為映射鍵並動態添加遇到的子類)。

請注意,以上兩個示例將"fallback"用作未滿足謂詞的情況的值。 您可以簡單地將其替換為null以獲得與問題代碼相同的后備結果。

為了使您的一線工作,我將邏輯“轉”為類似以下內容:

Object body = exchange.getIn().getBody();
Stream.of(
  new Pair<Class, String>(Foo.class, "toFoo"), 
  new Pair<Class, String>(Bar.class, "toBar"))
      .filter(pair -> body != null && body.getClass().isAssignableFrom(pair.getKey())))
      .findFirst()
      .map(Pair::getValue)
      .orElse("default");

;

暫無
暫無

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

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