如何使用collect
方法在嵌套的ifPresent
方法中进行收集?
到目前为止,这就是我所拥有的:
List result = list.stream()
.findFirst()
.ifPresent(info -> {
info.getMap()
.stream()
.filter( entry -> entry.getKey().equals("test"))
.map(entry::getValue)
.collect(Collectors.toList())
});
答案 0 :(得分:4)
你可能想这样做:
List result = list.stream()
.limit(1)
.flatMap(info -> // <-- removed brace {
info.getMap().stream()
.filter( entry -> entry.getKey().equals("test"))
.map(entry::getValue)
) // <-- removed brace here too
.collect(Collectors.toList());
让我解释一下:
.limit(1)
:仅将流限制为第一个元素(如果初始流为空,则返回空流)
.flatMap()
:将流映射到新流。在这种情况下,将返回由Entry#getValue()
的值组成的新流
.collect(Collectors.toList())
:最后将值流收集到列表中。
正如OlivierGrégoire在评论中所说,以下内容也有效:
List result = list.stream()
.limit(1)
.flatMap(info -> info.getMap().stream())
.filter( entry -> entry.getKey().equals("test"))
.map(entry::getValue)
.collect(Collectors.toList());
在我看来,更可读和更清楚地表明意图是什么。
答案 1 :(得分:3)
假设info.getMap
返回java.util.Map
,我根本不知道为什么你需要内部流管道。
只需使用get("test")
获取"test"
密钥的值:
List result =
list.stream()
.map(info -> info.getMap().get("test"))
.filter(Objects::nonNull)
.limit(1)
.collect(Collectors.toList());
P.S。,不要使用原始类型。您应该将返回列表的类型更改为List<ValueType>
,其中ValueType
是info.getMap()
Map
中值的类型。
答案 2 :(得分:1)
看起来您的List<Info>
包含零个或多个Info
个,其中Info
是某个对象,其getMap()
方法返回Map<String, Something>
并且你想得到List<Something>
,这是第一个列表项的地图的所有值都有关键测试。
您希望map
是可选的,而不是使用ifPresent
。 ifPresent
是一个终端操作,它不返回任何内容(只执行代码)。
list // List<Info>
.stream() // Stream<Info>
.findFirst() // Optional<Info>
.map(info -> info.getMap().entrySet() // Set<Entry<String, Something>>
.stream() // Stream<Entry<String, Something>>
.filter(entry -> entry.getKey().equals("test"))
.map(Entry::getValue) // Stream<Something>
.collect(toList()) // List<Something>
) // Optional<List<Something>>
.orElse(Collections::emptyList) // List<Something>
如果未指定最后一行,那么您将获得Optional<List<Info>>
返回。
编辑:Lino对limit
的回答更加惯用,除非你真的想以这种方式使用Optional
,否则选择那个。
假设您的上述代码是您完整的业务逻辑,您可能只是在列表的第一项中找到“test”的值(感谢Lino为limit
)。那就是:
list.stream() // Stream<List<Info>>
.limit(1) // Stream<List<Info>> count 0/1
.flatMap(info::getMap) Stream<Map<String, Something>> 0/1
.map(map -> map.get("test")) Stream<Something> 0/1, possibly null
.filter(Objects::nonNull) Stream<Something> 0/1
.findFirst() Optional<Something>
为了完整起见,如果您想在列表中的地图中找到“test”的任何值,那么它将是:
list.stream() // Stream<List<Info>>
.flatMap(info::getMap) Stream<Map<String, Something>>
.flatMap(map -> map.entrySet().stream()) // Stream<Entry<String, Something>>
.filter(entry -> entry.getKey().equals("test"))
.map(Entry::getValue) // Stream<Something>
.collect(toList()) // List<Something>