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