Java 8中的IntStream forEach方法

时间:2015-12-09 12:39:50

标签: java lambda

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

虽然我还在学习(并且不熟悉)lambdas。

我有一个问题。

这是我迄今所理解的(希望我是对的) -

  1. 只有一种抽象方法的Boolean[] myTaskParams = { true, true, true }; myAsyncTask = new myAsyncTask ().execute(myTaskParams); interface,例如functional interface具有IntConsumer方法的accept(仅抽象方法)。

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

  3. 现在,在做foreach时我们给出一个lambda表达式 -

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

    foreach中的Intstream方法需要IntConsumerfunctional interface)作为其类型。

    所以,基本上这里有这个lambda表达式,我们提供了implementation accept IntCosumer方法{/ 1}}。

    直到现在。

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

    现在,我的问题是" 它如何知道它必须遍历元素"

    Lambda表达式只决定了为每个元素做了什么,但谁决定它必须循环。

    我期待与此相当的东西 -

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

2 个答案:

答案 0 :(得分:1)

这是由于多态

希望你看过这种代码:

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

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

IntStream中也是如此。 IntStream是一个界面。因此,在int数组上调用stream时实际发生的是它调用了许多其他方法,最后在StreamSupport.class中找到了这样的方法:

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

在此方法中,它会返回new IntPipeline.Head。因此IntStream返回的stream实际上是IntPipeline.Head。现在,如果我们查看IntPipeline.Head类,您将看到for each方法的实现:

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

嗯,它不是预期的,是吗?它调用了另一堆方法!是否自己选择是否实施其他方法。

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

答案 1 :(得分:0)

正如javadoc所说:

  

对此流的每个元素执行操作。

它是一种抽象方法,因此无法实现。实施的责任(并遵循抽象方法的目的)是扩展IntStream的类。