我认为即使谓词无效,Stream.filter() 也不会显示编译时错误
I think that the Stream.filter() is not showing compile time error even with an invalid predicate
在下面的代码中我有这一行:stream.filter(Data::isEven);
我正在使用 filter()
并且 filter()
接受 Predicate
接口作为参数。我们都知道 Predicate
有一个带有签名的方法:public boolean test(T t);
它接受一个参数和 returns 一个布尔值。
我的理解是 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
的引用。
Data::isEven
是 Predicate
.
要调用此方法,您必须传递值,例如:myData.isEven()
。
这与 isEven(myData)
相同。所以区别仅在于语法(参数在点之前或括号内),但在语义上是相同的。
因此 isEven
是 Predicate<Data>
因为它接受 Data
和 returns Boolean
.
As others wrote "Data::isEven" or "data -> data.isEven()" 在这里是谓词。当我们调用这个谓词的 test 方法时,我们将 data 的实例(你有一个这样的实例流)作为参数传递给那里。
在下面的代码中我有这一行:stream.filter(Data::isEven);
我正在使用 filter()
并且 filter()
接受 Predicate
接口作为参数。我们都知道 Predicate
有一个带有签名的方法:public boolean test(T t);
它接受一个参数和 returns 一个布尔值。
我的理解是 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
, aPrimary
, orsuper
, 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
的引用。
Data::isEven
是 Predicate
.
要调用此方法,您必须传递值,例如:myData.isEven()
。
这与 isEven(myData)
相同。所以区别仅在于语法(参数在点之前或括号内),但在语义上是相同的。
因此 isEven
是 Predicate<Data>
因为它接受 Data
和 returns Boolean
.
As others wrote "Data::isEven" or "data -> data.isEven()" 在这里是谓词。当我们调用这个谓词的 test 方法时,我们将 data 的实例(你有一个这样的实例流)作为参数传递给那里。