我从不受我控制的服务中获取了一张可能为空的服务,并且想要处理它,比如说,过滤,映射和缩减为我需要的单个元素。
问题:是否有从“可选”到“流”的“链接”?
我试过(除其他外):
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并确保它不为空时,它会起作用。
答案 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();
如果事情陷入困境,总是试图寻找更好的方法。