为什么Lambda里面的地图没有运行? [英] Why lambda inside map is not running?
问题描述
我正在尝试在Java 8中学习并发性和lambda。但是我的代码未在map中输入lambda块。
I am trying to learn concurrency and lambdas in java 8. But my code is not entering lambda block inside map.
List<Book> bookList = new ArrayList<Book>();
isbnList
.stream()
.map(isbn -> (CompletableFuture.supplyAsync( () -> {
try {
List<String> pageContents = getUrlContents(webLink + isbn);
return new Book(
parseBookTitle(pageContents),
isbn,
parseRank(pageContents)
);
} catch (IOException ex) {
return null;
}
})).thenApply(a -> bookList.add(a))
);
在调试时,代码在.map行退出,并且我得到了空的bookList。相同的顺序代码给我正确的结果。
While debugging, code is exiting at .map line and I m getting empty bookList. Sequential code for same is giving me correct result.
推荐答案
流管道是 lazy 。如果没有终端操作,您的流管道甚至不会执行。 Stream.map
是中间操作,因此它不会触发管道执行。
A stream pipeline is lazy. Without a terminal operation, your stream pipeline is not even executed. Stream.map
is an intermediate operation so it won't trigger pipeline execution.
现在,您可以添加 forEach
步骤,使用lambda表达式 cf -> cf.join()
用于加入创建的 CompletableFuture
实例,以执行管道,并等待每个异步期货完成。但是这样做会破坏使用异步期货的全部目的,因为您要依次提交它们,并等待每一个完成,然后再提交下一个。
Now you could add a forEach
step with the lambda expression cf -> cf.join()
for joining on your created CompletableFuture
instances for your pipeline to be executed and wait for each of your async futures to complete. But doing this way will defeat the whole purpose of using asynchronous futures, because you're submitting them sequentially and waiting on the completion of each one before submitting the next one.
更好的是,您可以将流转换为 parallel 流,通过删除直接将
部分,并使用 map
与异步lambda主体一起使用CompletableFuture.supplyAsync collect
进行收集,以获得类似的效果,而不会造成额外的混乱。
Better yet, you could convert your stream to a parallel stream, use map
with your async lambda body directly by removing the CompletableFuture.supplyAsync
part and collecting with collect
for a similar effect without the extra clutter.
List<Book> bookList = isbnList.parallelStream()
.map(isbn -> {
try {
List<String> pageContents = getUrlContents(webLink + isbn);
return new Book(
parseBookTitle(pageContents),
isbn,
parseRank(pageContents)
);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}).collect(Collectors.toList());
进一步阅读:流API Javadoc中的流操作和管道。
这篇关于为什么Lambda里面的地图没有运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!