Java 8可选,多过滤器和多映射

Java 8可选,多过滤器和多映射,java,java-8,Java,Java 8,我想使用Java8,如何在Java8中将命令式风格转变为函数式风格 例如,假设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"; } 也许是像这样

我想使用Java8,如何在Java8中将命令式风格转变为函数式风格

例如,假设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");
我的问题是映射已经是一个字符串,所以我无法使它成为一行:

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

您要做的是模式匹配,这不是可选的。您可以滥用可选选项来获得产生所需结果的内容,例如

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"));
但是这显然不是真正的胜利,尤其是当你考虑更多的情况时会发生什么。

实现目标的一种方法是通过映射关联谓词和结果:

但对于更多的情况,最好以允许高效查找的方式编码谓词,例如使用类作为映射键并动态添加遇到的子类


请注意,上面的两个示例使用回退作为未满足谓词的情况下的值。您可以简单地将其替换为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");

)

color=to+exchange.getIn.getBody.getClass.getSimpleName;我不明白这段代码与可选、筛选和/或映射操作有什么关系。不要这样做。将方法getColor添加到返回正确颜色的getBody的返回类型中。然后可以将代码重构为字符串color=exchange.getIn.getBody.getColor;你能让Foo和Bar实现一个公共接口吗?你真正想要的是,java并没有提供现成的接口。在我看来,这是对期权的滥用,你在做什么。也就是说,Java9将有一个适用于您的方法的框架。另外,对于lambdasin中的类型检查,Foo.class::isInstance可能比Arrays.asLista,b.stream更简洁。您可以简单地使用stream.ofa,b。您应该决定变量的名称是color还是result,但根本不需要修改StringBuilder,只需使用.mapPair::getValue.orElse…而不是ifPresent。
alternatives.put(Baz.class::isInstance, "toBaz");
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");