在官方Java教程中阐明Lambda表达式的工作原理
我读了一遍又一遍,只是不理解方法6的最后一部分 具体而言,本部分:在官方Java教程中阐明Lambda表达式的工作原理,java,Java,我读了一遍又一遍,只是不理解方法6的最后一部分 具体而言,本部分: public static void printPersonsWithPredicate( List<Person> roster, Predicate<Person> tester) { for (Person p : roster) { if (tester.test(p)) { p.printPerson(); } }
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
公共静态void printPersonsWithPredicate(
列表(列表、谓词测试仪){
人员(p:名册){
if(测试仪测试(p)){
p、 printPerson();
}
}
}
因此,以下方法调用与在方法3中调用PrintPerson时相同:在本地类中指定搜索条件代码以获取符合选择性服务条件的成员:
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
printPersonsWithPredicate(
名册
p->p.getGender()==Person.Sex.MALE
&&p.getAge()>=18
&&p.getAge()lambda表达式是的主体的定义,它将Person
作为参数。我们之所以知道这一点,是因为printPersonsWithPredicate
声明为使用谓词,lambda将作为参数传递给该谓词
lambda的语法是->
的左侧是所定义方法的参数列表:
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
(Person p)->p.getGender()==Person.Sex.MALE
&&p.getAge()>=18
&&p.getAge()…
类似于lambda的匿名类如所示。一般来说:该参数仅根据相关函数接口的类型签名推断,包括对泛型参数的任何附加限制
在本例中,我们知道第二个参数是谓词
。由于谓词
是与方法的函数接口,我们知道p
的类型是T
(而不是谓词
)
由于T
通过printPersonsWithPredicate(列表花名册,谓词测试员)
的签名限制为Person
,因此p
的实际类型为Person
RE:UPDATE-答案是“是”和“否”:
“是”,一般来说,类型推断的顺序可以这样描述
“否”,理由如下:
- 在2.2中,我认为最好声明该方法将
T
的类型限制为Person
。类型“人”只是允许的“公分母”。例如:如果方法的签名将包含:
谓词
-那么参数类型实际上就是对象
- 最好说明编译器推断出的有关类型的内容,而不是由编译器以外的其他东西“隐式定义”的内容。您可能会认为这是一个吹毛求疵的问题,但这种转变有两个重要的后果:
- 它可以将你从“不是X不等于N,而是Y”的推理陷阱中拯救出来
- 非常具体地说,由于编译器能够推断一种类型的
谓词
是合法的,因此无需实际创建实现函数接口的新匿名类。事实上,在Java8当前的JDK中,就是这样发生的。解释细节
仅解决更新问题
1) 谓词接口已在java.util.function中定义
正确的
2) 通过在方法参数中将谓词声明为Person:
不对
实际上,您将tester
声明为谓词
。这里根本没有声明谓词<代码>谓词
是标准库声明的标准接口
2a)我们用一种类型的Person隐式实现谓词
对。。。某种程度上。您正在显式地实现它。这里需要的lambda类型是明确指定的。。。通过printPersonsWithPredicate
的方法签名。特别是,因为您将形式参数tester
声明为具有类型谓词
2b)当使用泛型类型T(或缺少泛型类型T)调用该方法时,该类型由该方法隐式推断为Person
在这种情况下不行。谢谢,这对我来说很有意义。然而,我还是有点困惑。根据你的回答,我更新了我的问题,以澄清我的理解。请让我知道我是否正确。@user3804927:我看到有人已经添加了关于更新的答案,但以防万一,我已经编辑了一个“洁净室”回复。谢谢,这对我来说是有意义的。然而,我还是有点困惑。根据你的回答,我更新了我的问题,以澄清我的理解。请让我知道我是否做对了我发现这段视频在30分钟时对“类型推断”有一个很好的解释,下面的一个答案没有给出。谢谢你,我真正困惑的部分是类型推断,这在上一篇文章中已经解释过,并在YouTube视频中进一步澄清。在处理布尔运算时,JDK 8引入了谓词的概念,并且通过类型推断(在Java中也是一个新概念),编译器能够确定p的类型。
import java.util.function // import the Predicate<T> interface
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
printPersonsWithPredicate(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25