使用基于Optional 内容的流

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

问题:从Optional到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但是Stream<Set> …有没有办法以某种方式flatMap一个集合或地图的可选?

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

你的错误在于这一行:

 .map(Stream::of) 

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

 .map(Set::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(); 

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

 Map map = getMap(); return map == null ? Optional. 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(); 

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