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

在下面的代码中,我有这一行: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;

    }

}


慕莱坞森
浏览 110回答 3
3回答

慕姐8265434

问题是,这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

繁星淼淼

Data::isEven是一个Predicate.要调用此方法,您必须传递值,例如:myData.isEven()。这本来就是一样的isEven(myData)。因此,区别仅在于语法(参数在点之前或括号内),但在语义上是相同的。因此isEven是 aPredicate<Data>因为它接受Data并返回Boolean。

饮歌长啸

正如其他人所写,“Data::isEven”或“data -> data.isEven()”在这里是谓词。当我们调用此谓词的测试方法时,我们将数据实例(您有此类实例的流)作为参数传递到那里。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java