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

标签 java lambda java-8 java-stream method-reference

在下面的代码中我有这一行:stream.filter(Data::isEven); 我正在使用 filter() 并且 filter() 接受 Predicate 接口(interface)作为参数。我们都知道 Predicate 有一个带有签名的方法:public boolean test(T t); 它接受一个参数并返回一个 boolean 值。

我的理解是,不接受任何参数的 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;
    }
}

最佳答案

Data::isEven 是一个方法引用,等同于 data -> data.isEven() 谓词:

Predicate<Data> predicate = data -> data.isEven();
// is the same as
Predicate<Data> predicate= Data::isEven;

这在 JLS 15.13 中有描述:

The target reference of an instance method (§15.12.4.1) may be provided by the method reference expression using an ExpressionName, a Primary, or super, or it may be provided later when the method is invoked.

....

Evaluation of a method reference expression produces an instance of a functional interface type (§9.8). Method reference evaluation does not cause the execution of the corresponding method; instead, this may occur at a later time when an appropriate method of the functional interface is invoked.

在您的例子中,Data::isEven 是对 Data 对象的实例方法 isEven 的引用。

关于java - 我认为即使谓词无效, Stream.filter() 也不会显示编译时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57845547/

相关文章:

java - 为什么 Java 中的 LinkedList 不是真正的链表?

java - 在 Java 中获取文件创建者/所有者属性

c++ - 返回调用指向成员函数的指定指针的 std::function 包装的 lambda

c# - 编写一个在 DbContext 重新创建之间重新计算的 LambdaExpression?

C++ lambda ;类工厂适配器

lambda - 自定义功能接口(interface)汇总统计

使用集合删除方法时不会出现 Java 并发修改异常

java - 扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

Java 流 : Is there a cleaner way of doing this?

java-8 - FreeMarker Java 8 可选值支持