为什么 lambda inside map 不是 运行?
Why lambda inside map is not running?
我正尝试在 java 8 中学习并发和 lambda。但是我的代码没有在 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。同样的顺序代码给了我正确的结果。
流管道惰性。如果没有 终端操作 ,您的流管道甚至不会执行。 Stream.map
是一个 中间操作 因此它不会触发管道执行。
现在您可以使用 lambda 表达式 cf -> cf.join()
添加一个 forEach
步骤,以加入您创建的 CompletableFuture
实例以执行您的管道并等待您的每个异步期货去完成。但是这样做会破坏使用异步期货的全部目的,因为您是按顺序提交它们并等待每个完成后再提交下一个。
更好的是,您可以将您的流转换为 并行 流,通过删除 CompletableFuture.supplyAsync
部分直接将 map
与您的异步 lambda 主体一起使用,并且使用 collect
收集以获得类似的效果,而不会造成额外的混乱。
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());
进一步阅读:Stream operations and pipelines 在流 API javadoc.
我正尝试在 java 8 中学习并发和 lambda。但是我的代码没有在 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。同样的顺序代码给了我正确的结果。
流管道惰性。如果没有 终端操作 ,您的流管道甚至不会执行。 Stream.map
是一个 中间操作 因此它不会触发管道执行。
现在您可以使用 lambda 表达式 cf -> cf.join()
添加一个 forEach
步骤,以加入您创建的 CompletableFuture
实例以执行您的管道并等待您的每个异步期货去完成。但是这样做会破坏使用异步期货的全部目的,因为您是按顺序提交它们并等待每个完成后再提交下一个。
更好的是,您可以将您的流转换为 并行 流,通过删除 CompletableFuture.supplyAsync
部分直接将 map
与您的异步 lambda 主体一起使用,并且使用 collect
收集以获得类似的效果,而不会造成额外的混乱。
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());
进一步阅读:Stream operations and pipelines 在流 API javadoc.