Java lambda在一个ifPresent中收集
如何使用Java lambda在一个ifPresent中收集,java,lambda,java-8,java-stream,collectors,Java,Lambda,Java 8,Java Stream,Collectors,如何使用collect方法在嵌套的ifPresent方法中进行收集 到目前为止,这就是我所拥有的: List result = list.stream() .findFirst() .ifPresent(info -> { info.getMap() .stream() .
collect
方法在嵌套的ifPresent
方法中进行收集
到目前为止,这就是我所拥有的:
List result = list.stream()
.findFirst()
.ifPresent(info -> {
info.getMap()
.stream()
.filter( entry -> entry.getKey().equals("test"))
.map(entry::getValue)
.collect(Collectors.toList())
});
您可能希望这样做:
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());
在我看来,它更具可读性,更清楚地表明了意图。它看起来像是一个
列表
包含零个或多个信息
,其中信息
是一个对象,它有一个getMap()
方法返回一个映射
,而您希望最终得到一个列表
,这是第一个列表项的映射中具有键测试的所有值
您希望映射
可选项,而不是使用ifPresent
ifPresent
是一种终端操作,它不返回任何内容(只执行代码)
为了完整性,如果您想在列表中的映射中找到“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>
list.stream()//流
.flatMap(info::getMap)流
.flatMap(map->map.entrySet().stream())//流
.filter(entry->entry.getKey().equals(“test”))
.map(条目::getValue)//流
.collect(toList())//列表
假设info.getMap
返回一个java.util.Map
,我不明白为什么需要内部流管道
只需使用get(“test”)
获取测试“
键的值:
List result =
list.stream()
.map(info -> info.getMap().get("test"))
.filter(Objects::nonNull)
.limit(1)
.collect(Collectors.toList());
注意,不要使用原始类型。您应该将返回列表的类型更改为
list
,其中ValueType
是info.getMap()中的值类型
Map
为什么它必须是如果存在
?在这种情况下,为什么不是flatMap
?或者更确切地说是map()。另外,不要使用原始类型。为什么要在映射的键上过滤它呢?这意味着你在迭代所有元素,而映射的存在就是为了避免这种情况。那么为什么不直接使用info.getMap().get(“test”)
?类似于Optional result=list.stream().findFirst().flatMap(info->Optional.ofNullable(info.getMap().get(“test”))代码>--为什么您首先需要一个列表作为结果类型?我在我的答案中添加了第二个编辑,并举例说明OP可能会尝试做什么(基于上述注释)。我认为我们有一套全面的方法来回答他/她目前试图做的任何类型的实现:)在.map(entry::getValue)
类中entry
?还是一个变量?这实际上是我从OP的代码中复制的一个打字错误。它应该是Entry::getValue
(调用Entry
上的getValue
方法,调用entrySet()
时,该iirc是容器类型)。如果您像上面的过滤器中那样使用entry->entry.getValue()
,则它将是entry
。修正我的答案(但同样,Lino的答案更惯用)。我认为你的答案比我的好,我不知道可选的#map()
甚至存在:)关于OP问题的评论正在挖掘他为什么这样做的原因,呵呵,但我想我们都只是为了正确使用流来回答:)。我更喜欢你的,因为它消除了列表
和可选
(更简洁)之间不必要的转换。我认为你应该调用info.getMap().entrySet().stream(),而不是info.getMap().stream(),来获取流值,对吗?flatMap接受流返回函数。你内心的lambda不会这么做。你应该.flatmap(info->info.getMap().stream()).filter(…).map(…).collect(…)
@OlivierGrégoire我认为你的版本只是有不同的语义,但总的来说它们是相同的。我更新了答案,也为你指明了方向:)你是对的。对我来说,现在是清晨,我还没有喝咖啡。
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>
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>
List result =
list.stream()
.map(info -> info.getMap().get("test"))
.filter(Objects::nonNull)
.limit(1)
.collect(Collectors.toList());