Java-8中Stream的循环融合(内部如何工作) [英] Loop fusion of Stream in Java-8 (how it works internally)

查看:36
本文介绍了Java-8中Stream的循环融合(内部如何工作)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在读《 Java in Action》一书.

I'm reading the book 'Java in Action'.

我在书中看到了Stream的示例代码.

And I saw an example code of Stream in the book.

List<String> names = menu.stream()
                         .filter(d -> {
                                       System.out.println("filtering" + d.getName());
                                       return d.getCalories() > 300;
                                      })
                         .map(d -> {
                                    System.out.println("mapping" + d.getName());
                                    return d.getName();
                                    })
                         .limit(3)
                         .collect(toList());

执行代码后,结果如下.

When the code is executed, the result is as follows.

filtering __1__.
mapping __1__.
filtering __2__.
mapping __2__.
filtering __3__.
mapping __3__.

也就是说,由于 limit(3),该日志消息仅被打印3次!在本书中,这被称为循环融合".但是,我不明白这一点.因为,如果知道对象是否被过滤,则必须计算过滤函数.然后,我认为应该打印正在过滤..."消息.

That is, because of limit(3), the log message is printed only 3 times! In this book, this is called in "loop fusion." But, I don't understand this. Because, if you know whether an object is filtered, you have to calculate the filtering function. Then, "filtering ..." message is should be printed, I think.

请,请向我说明循环融合在内部如何工作.

Please, Explain me about how the loop fusion works internally.

推荐答案

因为,如果[您想知道]是否已过滤对象,则必须计算过滤函数",这是正确的,但也许您的示例数据不足以说明这一点.如果您尝试

"Because, if you [want to] know whether an object is filtered, you have to calculate the filtering function", is right, but perhaps your sample data wasn’t sufficient to illustrate the point. If you try

List<String> result = Stream.of("java", "streams", "are", "great", "stuff")
    .filter(s -> {
                  System.out.println("filtering " + s);
                  return s.length()>=4;
                 })
    .map(s -> {
               System.out.println("mapping " + s);
               return s.toUpperCase();
              })
    .limit(3)
    .collect(Collectors.toList());
System.out.println("Result:");
result.forEach(System.out::println);

它将打印

filtering java
mapping java
filtering streams
mapping streams
filtering are
filtering great
mapping great
Result:
JAVA
STREAMS
GREAT

显示

  • 为了找到与过滤器匹配的三个元素,您可能必须评估三个以上的元素,这里,四个元素被评估,但是您不需要评估后续的元素一旦你有三场比赛

  • In order to find three elements matching the filter, you might have to evaluate more than three elements, here, four element are evaluated, but you don’t need to evaluate subsequent elements once you have three matches

后续映射功能仅需要应用于 matching 元素.这可以得出结论,是否指定了 .map(...).limit(...) .limit(...).map(...)是无关紧要的.
这与相关的 .filter .limit 的相对位置不同.

The subsequent mapping function only need to be applied to matching elements. This allows to conclude that it is irrelevant whether .map(…).limit(…)or .limit(…).map(…) was specified.
This differs from the relative position of .filter and .limit which is relevant.

术语循环融合"意味着没有过滤循环,映射循环,限制操作,但只有一个循环(概念上)完成了整个工作,等效于以下单个循环:

The term "loop fusion" implies that there is not a filtering loop, followed by a mapping loop, followed by a limit operation, but only one loop (conceptionally), performing the entire work, equivalent to the following single loop:

String[] source = { "java", "streams", "are", "great", "stuff"};
List<String> result = new ArrayList<>();
int limit = 3;
for(String s: source) {
    System.out.println("filtering " + s);
    if(s.length()>=4) {
        System.out.println("mapping " + s);
        String t = s.toUpperCase();
        if(limit-->0) {
            result.add(t);
        }
        else break;
    }
}

这篇关于Java-8中Stream的循环融合(内部如何工作)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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