Java 8 Lambdas并编写非脆弱的代码

时间:2018-04-08 18:14:36

标签: java lambda

背景:学习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)

我的理解: 名册是Person类型的列表。 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

2 个答案:

答案 0 :(得分:0)

表达式了解电子邮件的类型,因为Consumer<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); } } } 具有相同的Y.此外,正如评论中所说,您可以使用任何名称而不是电子邮件。

simple app

答案 1 :(得分:0)

<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent "> <FrameLayout android:id="@+id/map_frameview" android:layout_width="match_parent" android:layout_height="200dp"> </FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingTop="20dp"> </LinearLayout> </LinearLayout> </ScrollView> 方法有四个参数,一个processPersonsWithFunction表示人,一个List<Person>表示一个函数可以接受一个参数并返回Predicate<Person>,一个{{ 1}表示一个函数,它接受一个boolean类型的参数并返回一个Function<Person, String>,最后一个Person表示一个函数,该函数接受一个参数并且不返回任何内容(void)。

至于:

  

变量电子邮件如何被突然介绍和使用?!!!是   这只是魔术,或者是因为有1个返回值,我们可以   只需在这里调用电子邮件变量吗?

您可以根据需要为lambda命名参数,它只是另一个标识符。

为了扩展这一点, lambda 包含三件事。

  1. 您可以为任何名称命名的参数。
  2. 代码块,即行为。
  3. 自由变量的值,即不是参数且未在代码中定义的变量。
  4. 在您的情况下,作者很可能将lambda参数命名为“email”,因为它对其他程序员来说更具可读性和意义。但是,没有什么可以阻止你做

    String

    就像使用单个字母参数传递给方法Consumer<String>的其他lambda一样。