java - Java 8 中的 IntStream forEach 方法

标签 java lambda

我正在尝试学习 java8 中引入的新概念。

虽然我仍在学习(并且不太熟悉)lambda。

我有一个问题。

这是我到目前为止所理解的(希望我是对的)-

  1. 只有一个抽象方法的接口(interface)是一个功能接口(interface),例如IntConsumer 具有 accept 方法(仅抽象方法)。

  2. 我们编写一个 lambda 表达式并提供此方法的实现。

现在,在执行 foreach 时,我们给出一个 lambda 表达式 -

(值 -> System.out.printf("%d ", value))

Intstream 中的 foreach 方法采用 IntConsumer(一个函数式接口(interface)) 作为其类型。

因此,基本上,通过这个 lambda 表达式,我们提供了 IntCosumeraccept 方法的实现

到目前为止还好。

然后,我检查了Intstream的源代码,发现foreach是一个抽象方法,没有实现。

现在,我的问题是“它如何知道它必须迭代元素”

Lambda 表达式仅规定了对每个元素执行的操作,但谁规定了它必须循环。

我期待类似的东西 -

foreach(IntConsumer cons){
     for(Integer i : this){
       cons.accept();
     }
}

最佳答案

这是由于多态性造成的。

希望您已经看到过这种代码:

interface SomeInterface { ... }
class SomeClass implements SomeInterface { ... }
...
private SomeInterface someMethod() {
    ...
    return new SomeClass();
}

someMethod 应该返回 SomeInterface,但它返回一个 SomeClass。这怎么可能?因为 SomeClass 实现了 SomeInterface

同样的情况也发生在IntStream中。 IntStream 是一个接口(interface)。因此,当您在 int 数组上调用 stream 时,实际发生的情况是它调用了一堆其他方法,最后您在 StreamSupport.class 中达到了这样的方法:

public static IntStream intStream(Spliterator.OfInt spliterator, boolean parallel) {

在此方法中,它返回一个new IntPipeline.Head。所以stream返回的IntStream实际上是一个IntPipeline.Head。现在,如果我们查看 IntPipeline.Head 类,您将看到 foreach 方法的实现:

    @Override
    public void forEach(IntConsumer action) {
        if (!isParallel()) {
            adapt(sourceStageSpliterator()).forEachRemaining(action);
        }
        else {
            super.forEach(action);
        }
    }

嗯,这不是它所期望的,是吗?它调用了另一堆方法!是否看他们如何实现其他方法是你自己的选择。

现在的问题是,为什么他们不直接在 stream 方法中返回 IntPipeline.Head 呢?这是因为返回 IntPipeline.Head 只是标准 JDK 的行为。其他人可以创建自己的 IntStream 实现,并让 stream 返回其实现。这提高了灵 active 。

关于java - Java 8 中的 IntStream forEach 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34179062/

相关文章:

java - java中的继承问题

c# - 如何测试表达式是否相等

c++ - C++ lambda 和静态变量的预期行为

java - 这个Java场景内存泄漏在哪里呢?

java - 连接到 ActiveMQ 服务器的 Android 应用程序

java - 从 Github 安装 Gson

java - 如何在 Tomcat 中运行 Java EE 项目?

带有 lambda 的 Java 默认方法

c++ - 围绕成员函数的 C++ lambda 包装器如何在析构函数之后工作?

c# - 将 lambda 表达式用于事件处理程序