为什么Lambda里面的地图没有运行? [英] Why lambda inside map is not running?

查看:88
本文介绍了为什么Lambda里面的地图没有运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆