Java Lambda 表达式
最后修改时间:2025 年 4 月 17 日
Lambda 表达式是 Java 8 中引入的,是 Java 中函数式编程的基石。它们允许开发人员通过提供函数式接口的内联实现来编写简洁、富有表现力的代码。本教程探讨它们的语法、用例和实际应用。
本教程探讨 Java lambda 表达式,它是 Java 8 中引入的一项强大功能,可以实现简洁而富有表现力的函数式编程。 Lambda 表达式简化了函数式接口的实现,并简化了排序、过滤和映射数据等操作。
Java 中 lambda 表达式的基本语法如下:
(parameters) -> expression
(parameters) -> { statements; }
Lambda 表达式提高了代码的可读性和简洁性,使开发人员能够编写更易于维护和高效的 Java 应用程序。
参数类型声明是可选的; Java 编译器可以从上下文中推断类型。对于单个参数,括号是可选的,但对于多个参数或没有参数,括号是必需的。对于单语句主体,花括号是可选的,如果主体由返回值的单个表达式组成,则不需要 return 关键字。但是,当使用多个语句显式返回值时,花括号是必需的。
对数组进行排序
排序数组是编程中的常见任务,lambda 表达式通过提供一种简洁的方式来定义比较逻辑,从而使其变得更容易。以下示例演示了使用 lambda 表达式按字母顺序对字符串数组进行排序。
package com.zetcode;
import java.util.Arrays;
public class LambdaSortEx {
public static void main(String[] args) {
String[] words = { "kind", "massive", "atom", "car", "blue" };
Arrays.sort(words, (s1, s2) -> s1.compareTo(s2));
System.out.println(Arrays.toString(words));
}
}
此示例演示了如何使用带有 lambda 表达式的 Arrays.sort 方法对字符串数组进行排序。 lambda 表达式 (s1, s2) -> s1.compareTo(s2) 定义了比较逻辑,从而生成按字母顺序排序的数组。
$ java com/zetcode/LambdaSortEx.java [atom, blue, car, kind, massive]
函数式接口和 Lambda 表达式
函数式接口(包含单个抽象方法)是 Java 中 lambda 表达式的基础。 Lambda 表达式提供了一种紧凑的方式来实现这些接口,从而实现灵活且可重用的代码结构。
实现问候服务
创建自定义函数式接口允许开发人员定义特定的行为。此示例演示了如何使用 lambda 表达式来实现一个简单的问候服务,该服务将消息输出到控制台。
package com.zetcode;
interface GreetingService {
void greet(String message);
}
public class LambdaGreetingEx {
public static void main(String[] args) {
GreetingService gs = msg -> System.out.println(msg);
gs.greet("Good night");
gs.greet("Hello there");
}
}
在此示例中,定义了一个具有单个 greet 方法的 GreetingService 函数式接口。 lambda 表达式实现了此接口,并在调用 greet 方法时将消息打印到控制台。
$ java com/zetcode/LambdaGreetingEx.java Good night Hello there
常见的函数式接口
java.util.function 包提供了一组内置的函数式接口,例如 Function、Consumer、Supplier 和 Predicate。这些接口支持常见的函数式编程模式,使 lambda 表达式更加通用。
使用 Function 接口
Function 接口非常适合于接受输入并产生输出的操作。此示例使用 lambda 表达式来定义一个计算整数平方的函数。
package com.zetcode;
import java.util.function.Function;
public class LambdaFunctionEx {
public static void main(String[] args) {
Function square = x -> x * x;
System.out.println(square.apply(5));
}
}
此示例使用 Function 接口来定义一个计算整数平方的 lambda 表达式。 apply 方法执行 lambda,返回结果。
$ java com/zetcode/LambdaFunctionEx.java 25
使用流过滤数据
Java 流与 lambda 表达式相结合,提供了一种强大的数据集合处理方式。此示例演示了基于 lambda 表达式定义的条件过滤对象列表。
package com.zetcode;
import java.util.List;
import java.util.stream.Collectors;
public class LambdaFilterEx {
public static void main(String[] args) {
List<User> persons = List.of(
new User("Jack", "jack234@gmail.com"),
new User("Peter", "pete2@post.com"),
new User("Lucy", "lucy17@gmail.com"),
new User("Robert", "bob56@post.com"),
new User("Martin", "mato4@imail.com")
);
List<User> result = persons.stream()
.filter(person -> person.email().matches(".*post\\.com"))
.collect(Collectors.toList());
result.forEach(p -> System.out.println(p.name()));
}
}
record User(String name, String email) {}
此示例在流中使用 lambda 表达式来根据其电子邮件域名过滤 User 对象。 filter 方法中的 lambda 表达式选择电子邮件以“post.com”结尾的用户,而 forEach 中的另一个 lambda 表达式则打印其姓名。
$ java com/zetcode/LambdaFilterEx.java Peter Robert
使用流映射数据
Java 流中的 map 方法允许开发人员使用 lambda 表达式转换数据。此示例演示了如何将字符串列表转换为其长度的列表。
package com.zetcode;
import java.util.List;
import java.util.stream.Collectors;
public class LambdaMapEx {
public static void main(String[] args) {
List<String> words = List.of("apple", "banana", "cherry");
List<Integer> lengths = words.stream()
.map(word -> word.length())
.collect(Collectors.toList());
System.out.println(lengths);
}
}
此示例演示了如何将 lambda 表达式与 map 方法结合使用,以将字符串列表转换为其长度的列表。 lambda word -> word.length() 计算每个单词的长度。
$ java com/zetcode/LambdaMapEx.java [5, 6, 6]
使用 Consumer 接口
Consumer 接口用于接受输入但不产生输出的操作,例如打印或修改数据。此示例使用 lambda 表达式来打印大写字符串。
package com.zetcode;
import java.util.function.Consumer;
public class LambdaConsumerEx {
public static void main(String[] args) {
Consumer<String> printUpperCase = text -> System.out.println(text.toUpperCase());
printUpperCase.accept("hello");
printUpperCase.accept("java lambda");
}
}
此示例使用 Consumer 接口来定义一个 lambda 表达式,该表达式将字符串转换为大写并将其打印出来。 accept 方法触发 lambda 的执行。
$ java com/zetcode/LambdaConsumerEx.java HELLO JAVA LAMBDA
使用 Supplier 接口
Supplier 接口用于生成值而不接受任何输入。此示例演示了一个生成随机问候语的 lambda 表达式。
package com.zetcode;
import java.util.function.Supplier;
public class LambdaSupplierEx {
public static void main(String[] args) {
Supplier<String> randomGreeting = () -> {
String[] greetings = {"Hello", "Hi", "Greetings"};
return greetings[(int) (Math.random() * greetings.length)];
};
System.out.println(randomGreeting.get());
System.out.println(randomGreeting.get());
}
}
此示例使用 Supplier 接口来创建一个 lambda 表达式,该表达式返回随机问候语。 get 方法检索由 lambda 产生的值。
$ java com/zetcode/LambdaSupplierEx.java Hi Greetings
组合谓词
Predicate 接口用于测试条件。此示例演示了如何使用逻辑运算组合多个谓词来过滤数据。
package com.zetcode;
import java.util.List;
import java.util.function.Predicate;
public class LambdaPredicateEx {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8);
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isGreaterThanFour = n -> n > 4;
List<Integer> result = numbers.stream()
.filter(isEven.and(isGreaterThanFour))
.toList();
System.out.println(result);
}
}
此示例组合了两个 Predicate lambda 表达式来过滤数字列表,仅选择大于 4 的偶数。 and 方法以逻辑方式组合了这些谓词。
$ java com/zetcode/LambdaPredicateEx.java [6, 8]
来源
有关更多阅读材料,请参阅有关 lambda 表达式的官方 Java 文档,该文档提供了对其语法和应用的详细见解。
本教程提供了 Java lambda 表达式的全面概述,包括其语法、与函数式接口的用法以及在排序、过滤、映射等方面的实际应用。
作者
列出所有Java教程。