在下面的代码中,我有这一行:stream.filter(Data::isEven); 我正在使用 afilter()并且 afilter()接受Predicate接口作为参数。我们都知道Predicate有一种带有签名的方法: public boolean test(T t); 它接受一个参数并返回一个布尔值。我的理解是,isEven()不接受参数的方法不是有效的谓词,因为与test()方法不同,它不接受任何参数,那么为什么我的代码没有显示编译时错误?import java.util.stream.Stream;public class Main App { public static void main(String args[]) { Stream<Data> stream = Stream.of(new Data(4), new Data(1)); stream.filter(Data::isEven); // should throw compile error but doesn't }}class Data{ int i; public Data(int i) { this.i=i; } public boolean isEven() { return i%2==0; }}
3 回答
慕姐8265434
TA贡献1813条经验 获得超2个赞
问题是,这Data::isEven
是一个相当于data -> data.isEven()
predicate 的方法引用:
Predicate<Data> predicate = data -> data.isEven(); // is the same as Predicate<Data> predicate= Data::isEven;
这在JLS 15.13
:
ExpressionName
实例方法(第 15.12.4.1 节)的目标引用可以通过使用、 aPrimary
或 的方法引用表达式来提供,super
也可以稍后在调用方法时提供。....
方法引用表达式的求值会生成函数接口类型的实例(第 9.8 节)。方法引用求值不会导致对应方法的执行;相反,这可能会在稍后调用功能接口的适当方法时发生。
在您的情况下是对对象实例方法的Data::isEven
引用。isEven
Data
繁星淼淼
TA贡献1775条经验 获得超11个赞
Data::isEven
是一个Predicate
.
要调用此方法,您必须传递值,例如:myData.isEven()
。这本来就是一样的isEven(myData)
。因此,区别仅在于语法(参数在点之前或括号内),但在语义上是相同的。
因此isEven
是 aPredicate<Data>
因为它接受Data
并返回Boolean
。
饮歌长啸
TA贡献1951条经验 获得超3个赞
正如其他人所写,“Data::isEven”或“data -> data.isEven()”在这里是谓词。当我们调用此谓词的测试方法时,我们将数据实例(您有此类实例的流)作为参数传递到那里。
添加回答
举报
0/150
提交
取消