为什么lambda里面的地图没有运行?

时间:2016-11-02 03:00:13

标签: lambda concurrency java-8 java.util.concurrent concurrent.futures

我正在尝试在java 8中学习并发和lambdas。但是我的代码没有在map中输入lambda块。

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。相同的顺序代码给了我正确的结果。

1 个答案:

答案 0 :(得分:7)

流管道 lazy 。如果没有终端操作,您的流管道甚至不会被执行。 Stream.map是一个中间操作,因此它不会触发管道执行。

现在,您可以使用lambda表达式cf -> cf.join()添加forEach步骤,以加入已创建的CompletableFuture实例,以便执行您的管道并等待每个异步期货完成。但是这样做会破坏使用异步期货的整个目的,因为你在提交下一个之前按顺序提交它们并等待每个期货的完成。

更好的是,您可以将流转换为并行流,直接使用map与异步lambda主体删除CompletableFuture.supplyAsync部分并使用{{1没有额外杂乱的类似效果。

collect

进一步阅读:流API javadoc中的Stream operations and pipelines