我正在尝试学习 java8 中引入的新概念。
虽然我仍在学习(并且不太熟悉)lambda。
我有一个问题。
这是我到目前为止所理解的(希望我是对的)-
只有一个抽象方法的
接口(interface)
是一个功能接口(interface)
,例如IntConsumer
具有accept
方法(仅抽象方法)。我们编写一个 lambda 表达式并提供此方法的实现。
现在,在执行 foreach 时,我们给出一个 lambda 表达式 -
(值 -> System.out.printf("%d ", value))
Intstream
中的 foreach
方法采用 IntConsumer
(一个函数式接口(interface))
作为其类型。
因此,基本上,通过这个 lambda 表达式,我们提供了 IntCosumer
的 accept
方法的实现
。
到目前为止还好。
然后,我检查了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/