我正在尝试学习java8中引入的新概念。
虽然我还在学习(并且不熟悉)lambdas。
我有一个问题。
这是我迄今所理解的(希望我是对的) -
只有一种抽象方法的Boolean[] myTaskParams = { true, true, true };
myAsyncTask = new myAsyncTask ().execute(myTaskParams);
是interface
,例如functional interface
具有IntConsumer
方法的accept
(仅抽象方法)。
我们编写一个lambda表达式并为此方法提供实现。
现在,在做foreach时我们给出一个lambda表达式 -
(value -> System.out.printf("%d ", value))
foreach
中的Intstream
方法需要IntConsumer
(functional interface)
作为其类型。
所以,基本上这里有这个lambda表达式,我们提供了implementation
accept
IntCosumer
方法{/ 1}}。
直到现在。
然后,我检查了Intstream
的源代码,发现foreach
是一个抽象方法,没有实现。
现在,我的问题是" 它如何知道它必须遍历元素" ?
Lambda
表达式只决定了为每个元素做了什么,但谁决定它必须循环。
我期待与此相当的东西 -
foreach(IntConsumer cons){
for(Integer i : this){
cons.accept();
}
}
答案 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
的类。