147. Java Lambda 表达式 - 调用 Lambda 表达式

42 阅读2分钟

147. Java Lambda 表达式 - 调用 Lambda 表达式

让我们回到前面提到的 Predicate 示例,并假设我们已经在方法中定义了这个 Predicate。接下来,如何使用它来测试给定的字符串是否确实是长度为 3 呢?

尽管我们使用了编写 lambda 的语法,但需要记住的是,这个 lambda 实际上是 Predicate 接口的一个实例。这个接口定义了一个名为 test() 的方法,该方法接受一个 String 类型的参数,并返回一个布尔值。

下面是一个方法示例:

List<String> retainStringsOfLength3(List<String> strings) {
    // 创建 Predicate 实例,通过 lambda 表达式来判断字符串长度
    Predicate<String> predicate = s -> s.length() == 3;
    
    List<String> stringsOfLength3 = new ArrayList<>();
    
    // 遍历输入的字符串列表,使用 test 方法判断字符串长度
    for (String s : strings) {
        if (predicate.test(s)) {  // 调用 lambda 表达式实现的 test 方法
            stringsOfLength3.add(s);
        }
    }
    return stringsOfLength3;
}
解析:
  • Predicate<String> predicate = s -> s.length() == 3; 这行代码定义了一个 Predicate 类型的 lambda 表达式,用于判断字符串的长度是否为 3lambda 表达式本质上是 Predicate 接口的实现,test 方法的实现代码就是 s.length() == 3
  • predicate.test(s)for 循环中,每次我们对 strings 列表中的字符串进行判断时,都会调用 Predicate 接口中的 test 方法,而这个方法的实现实际上就是我们定义的 lambda 表达式。
重点:

调用 lambda 时,实际是在调用接口 Predicate 中的抽象方法 test(),而该方法的实现就是我们提供的 lambda 表达式代码。

更简洁的写法

虽然上面的代码已经可以正常工作,但有更简洁的方式来利用 lambdaJava 8 中的新特性,结合流式操作来简化代码:

List<String> retainStringsOfLength3(List<String> strings) {
    return strings.stream()
                  .filter(s -> s.length() == 3)  // 使用 lambda 表达式进行过滤
                  .collect(Collectors.toList());
}

这里我们使用了 Java 8 中的 Stream API,通过 filter 方法直接过滤出符合条件的字符串。filter 方法的参数就是我们之前写的 Predicate 类型的 lambda表达式。

总结:

每次编写 lambda 表达式时,您都可以调用该 lambda 实现的接口中定义的任何方法。调用抽象方法时,实际上会执行 lambda 本身的代码,而调用 default 方法时,执行的是接口中提供的代码。

注意:
  • lambda 无法覆盖接口中的 default 方法,因为 default 方法已经有了具体实现,而 lambda 是用来实现接口的抽象方法的。
  • lambda 表达式本质上是对接口抽象方法的实现。

这样,我们就可以清楚地理解 lambda 表达式如何在实际代码中被调用,以及如何简化我们的代码。