为什么lambda inside map不运行?

为什么lambda inside map不运行?,lambda,concurrency,java-8,java.util.concurrent,concurrent.futures,Lambda,Concurrency,Java 8,Java.util.concurrent,Concurrent.futures,我正在努力学习Java8中的并发性和lambdas。但我的代码没有进入地图内的lambda块 List<Book> bookList = new ArrayList<Book>(); isbnList .stream() .map(isbn -> (CompletableFuture.supplyAsync( () -> { try { List<String> pageContent

我正在努力学习Java8中的并发性和lambdas。但我的代码没有进入地图内的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))
    );
List bookList=new ArrayList();
isbnList
.stream()
.map(isbn->(CompletableFuture.SupplySync)(()->{
试一试{
List pageContents=getUrlContents(webLink+isbn);
归还新书(
parseBookTitle(页面内容),
isbn,
parseRank(页面内容)
);
}捕获(IOEX异常){
返回null;
}
}))。然后应用(a->bookList.add(a))
);
调试时,代码在.map行退出,我得到的是空的bookList。相同的顺序代码给出了正确的结果。

流管道是惰性的。如果没有终端操作,甚至不会执行流管道。是一个中间操作,因此不会触发管道执行

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

更好的是,您可以将流转换为并行流,通过删除
CompletableFuture.supplyAsync
部分并使用
collect
进行采集,直接将
map
与异步lambda主体一起使用,以获得类似的效果,而不会产生额外的混乱

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());
List bookList=isbnList.parallelStream()
.map(isbn->{
试一试{
List pageContents=getUrlContents(webLink+isbn);
归还新书(
parseBookTitle(页面内容),
isbn,
parseRank(页面内容)
);
}捕获(IOEX异常){
抛出新的运行时异常(ex);
}
}).collect(Collectors.toList());

进一步阅读:在流API javadoc中。

用forEach替换了map,但控制仍然不在lambda块中。请给出建议。您正在将异步任务提交到公共fork-join池,但不等待结果。你需要确保你的任务已经完成。回到使用map,但在forEach中加入异步未来。我会更新我的答案。我将相应地更新我的答案。请注意,
Collection
s具有
parallelStream()
方法,该方法简化了
stream().parallel()
步骤。