背景:学习Java 8并且真正尝试拥抱新的lambda表达式,并且更聪明地编写代码。我按照这整篇文章(这可以很好地完成整个过程),直到下面的代码。突然之间,最后两个陈述的工作原理尚不清楚。
以下方法从有资格获得选择性服务的名册中包含的每个成员检索电子邮件地址,然后将其打印出来:
processPersonsWithFunction(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
我的理解:花名册是人物类型列表。 lambda表达式知道类型,因为我们已经设置了CheckPerson接口和Predicate接口。
p.getEmailAddress()通过List为每个循环调用Person类的方法getEmailAddress。不知道接下来会发生什么,变量电子邮件如何被引入和使用?!!!这只是魔术,还是因为有1个返回值,我们可以在这里调用电子邮件变量吗?
p -> p.getEmailAddress(),
email -> System.out.println(email)
这是processPersonsWithFunction
方法:
public static void processPersonsWithFunction(
List<Person> roster,
Predicate<Person> tester,
Function<Person, String> mapper,
Consumer<String> block) {
for (Person p : roster) {
if (tester.test(p)) {
String data = mapper.apply(p);
block.accept(data);
}
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
processPersonsWithFunction
方法有四个参数,一个List<Person>
代表人,一个Predicate<Person>
代表一个函数可以接受一个参数并返回一个boolean
,一个Function<Person, String>
代表一个函数,它接受一个Person
类型的参数并返回一个String
,最后一个Consumer<String>
代表一个获取一个参数并且不返回任何内容的函数(void)。
至于:
变量电子邮件如何突然被引入和使用?!!!这只是魔术,还是因为有1个返回值,我们可以在这里调用电子邮件变量吗?
您可以根据需要为lambda命名参数,它只是另一个标识符。
为了扩展这个,lambda由三件事组成。
在您的情况下,作者很可能将lambda参数命名为“email”,因为它对其他程序员来说更具可读性和意义。但是,没有什么能阻止你这样做
e -> System.out.println(e)
就像使用单个字母参数传递给方法processPersonsWithFunction
的其他lambda一样。
该表达式理解电子邮件的类型,因为Function<X, Y>
与Consumer<Y>
具有相同的Y.此外,正如评论中所说,您可以使用任何名称而不是电子邮件。
public static <X, Y> void processElements(
Iterable<X> source,
Predicate<X> tester,
Function <X, Y> mapper,
Consumer<Y> block) {
for (X p : source) {
if (tester.test(p)) {
Y data = mapper.apply(p);
block.accept(data);
}
}
}