为了账号安全,请及时绑定邮箱和手机立即绑定

我认为即使谓词无效,Stream.filter() 也不会显示编译时错误

我认为即使谓词无效,Stream.filter() 也不会显示编译时错误

慕莱坞森 2023-07-19 16:34:46
在下面的代码中,我有这一行: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引用。isEvenData


查看完整回答
反对 回复 2023-07-19
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

Data::isEven是一个Predicate.

要调用此方法,您必须传递值,例如:myData.isEven()。这本来就是一样的isEven(myData)。因此,区别仅在于语法(参数在点之前或括号内),但在语义上是相同的。

因此isEven是 aPredicate<Data>因为它接受Data并返回Boolean


查看完整回答
反对 回复 2023-07-19
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

正如其他人所写,“Data::isEven”或“data -> data.isEven()”在这里是谓词。当我们调用此谓词的测试方法时,我们将数据实例(您有此类实例的流)作为参数传递到那里。



查看完整回答
反对 回复 2023-07-19
  • 3 回答
  • 0 关注
  • 109 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信