Java 8可选,多个filter和多个map

标签 java java-8

我想使用Java 8,如何在java 8中将这种命令式风格转变为函数式风格Optional

例如,假设 exchange.getIn().getBody() 可能为 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");

最佳答案

您想要做的是模式匹配,这不是 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 即可获得与问题代码中相同的后备结果。

关于Java 8可选,多个filter和多个map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35065303/

相关文章:

java - List<E> 不喜欢我的自定义类

java - 形态学函数瓶颈的 OpenCV Android 程序

java - 转换 Java 8 流中的代码

java - 获取一年中的最后一个日期java 8

java - 如何将元素与对象列表匹配并返回对象

Java 8 - 填充 ArrayList

java - android 在屏幕底部对齐元素

java - Apache CXF 初始化上的调用方法

java - 在 JAR 文件中包含 AWS 凭证

java - 使用 Java8 列表到 map