使用基于Optional <map>

时间:2017-06-15 12:41:11

标签: java java-stream

我从不受我控制的服务中获取了一张可能为空的服务,并且想要处理它,比如说,过滤,映射和缩减为我需要的单个元素。

问题:是否有从“可选”到“流”的“链接”?

我试过(除其他外):

 return Optional.ofNullable(getMap())
   .map(Map::entrySet) // gets the entryset
   .map(Stream::of)
   .orElseGet(Stream::empty)
   // i would then like to continue with
   .filter(e -> e.getKey().startsWith("f")
   .map(Entry::getValue)
   .findFirst();

但是我得到的不是Stream<Entry>而是Stream<Set<Entry>> ...有没有办法以某种方式展示一个集合或地图的可选项?

注意:我对这里流畅,纯粹的流/可选方法感兴趣。当然,当我首先将地图保存到local var并确保它不为空时,它会起作用。

2 个答案:

答案 0 :(得分:8)

你的错误在于这一行:

.map(Stream::of)

of函数接受单个参数(或vararg参数),并返回仅包含该元素的流。因此,您将获得Stream<Set<Map.Entry>>。相反,您应该在entryset上调用stream方法,如下所示:

.map(Set::stream)

答案 1 :(得分:1)

我想我会回答这个问题。

 return Optional.ofNullable(getMap())
   .map(Map::entrySet) // gets the entryset
   .map(Stream::of)
   .orElseGet(Stream::empty)
   // i would then like to continue with
   .filter(e -> e.getKey().startsWith("f")
   .map(Entry::getValue)
   .findFirst();

当我看到上面的代码时,我生病了,真的生病了。用流利的方法编写代码而不是编写简单的代码真的如此重要吗?首先,正如@ Didier L在评论中提到的那样,使用Optional的方法是错误的。其次,代码很难读,不是吗?如果你用定义局部变量来写它:

Map<String, Integer> map = getMap();

return map == null ? Optional.<Integer> empty() 
                   : map.entrySet().stream()
                        .filter(e -> e.getKey().startsWith("f")).map(Entry::getValue).findFirst();

不是很清楚吗?或者你可以用StreamEx来做,如果你不能不使用流利的方法:

StreamEx.ofNullable(getMap())
        .flatMapToEntry(Function.identity())
        .filterKeys(k -> k.startsWith("f")).values().findFirst();

或我的图书馆AbacusUtil

EntryStream.of(getMap()).filterByKey(k -> k.startsWith("f")).values().first();

如果事情陷入困境,总是试图寻找更好的方法。