Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁的方式来表示匿名函数。Lambda 表达式主要用于简化函数式接口的实现,使代码更加简洁和易读。以下是关于 Lambda 表达式的详细阐述:
Lambda 表达式的语法如下:
(parameter_list) -> { 代码块 }
parameter_list
:参数列表,可以包含零个或多个参数,参数类型可以省略(由编译器自动推断)。->
:Lambda 操作符,将参数列表与 Lambda 主体分隔开。代码块
:Lambda 主体,包含实现函数式接口的代码。如果只有一行代码,可以省略 {}
和 return
语句。// 无参数
() -> System.out.println("Hello, World!");
// 单个参数
(x) -> x * x;
// 多个参数
(x, y) -> x + y;
// 带代码块
(x, y) -> {
int sum = x + y;
return sum;
};
Lambda 表达式的核心是函数式接口(Functional Interface)。函数式接口是指 仅包含一个抽象方法 的接口。Java 提供了 @FunctionalInterface
注解来标记函数式接口。
Runnable
:void run()
Consumer
:void accept(T t)
Supplier
:T get()
Function
:R apply(T t)
Predicate
:boolean test(T t)
@FunctionalInterface
interface MyInterface {
void doSomething();
}
// 使用 Lambda 表达式实现函数式接口
MyInterface myLambda = () -> System.out.println("Doing something");
myLambda.doSomething();
好好体会一下,lambda式是一个函数,他赋值给一个接口变量,那么这个接口一定要有一个抽象方法去实现,正好把lambda的这个函数赋值给这个未被重写的抽象类;而且这个接口一定只能有一个未实现方法,为什么呢,因为如果有多个,谁也分不清楚给哪个方法;有点意思!
Lambda 表达式可以替代匿名内部类,使代码更简洁。
// 传统匿名内部类
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};
// 使用 Lambda 表达式
Runnable r2 = () -> System.out.println("Hello, World!");
注意:以上代码中Runnable 就只是一个普通的函数式接口,只是起到举例子的效果,可以替换成自定义函数式接口
Lambda 表达式结合 forEach()
方法可以简化集合的遍历操作。
List list = Arrays.asList("Apple", "Banana", "Orange");
// 传统遍历
for (String s : list) {
System.out.println(s);
}
// 使用 Lambda 表达式
list.forEach(s -> System.out.println(s));
Lambda 表达式可以作为方法参数传递,特别适合用于需要回调函数的场景。
public static void processList(List list, Consumer consumer) {
for (String s : list) {
consumer.accept(s);
}
}
// 调用方法
processList(list, s -> System.out.println(s));
Lambda 表达式与 Stream API 结合,可以实现强大的数据处理功能,如过滤、映射、排序等。
List fruits = Arrays.asList("Apple", "Banana", "Orange", "Mango");
// 过滤长度大于 5 的字符串
List filtered = fruits.stream()
.filter(s -> s.length() > 5)
.collect(Collectors.toList());
// 将字符串转换为大写
List upperCase = fruits.stream()
.map(s -> s.toUpperCase())
.collect(Collectors.toList());
Lambda 表达式可以访问外部的局部变量、实例变量和静态变量,但有如下限制:
final
或实际上是 final
的(即不可变)。int num = 10; // 局部变量
Runnable r = () -> System.out.println(num); // num 必须是 final 或 effectively final
// 错误示例
int num2 = 20;
num2 = 30; // 修改 num2
Runnable r2 = () -> System.out.println(num2); // 编译错误:num2 必须是 final
方法引用是 Lambda 表达式的一种简化形式,用于直接引用已有的方法。方法引用的语法如下:
类名::方法名
ClassName::staticMethod
instance::instanceMethod
ClassName::instanceMethod
ClassName::new
List list = Arrays.asList("Apple", "Banana", "Orange");
// 使用 Lambda 表达式
list.forEach(s -> System.out.println(s));
// 使用方法引用
list.forEach(System.out::println);
好好理解上面的例子,还挺有意思,但是挺无聊;
感觉就是,有一个类他有很多方法,但是我就想要他的其中一个方法。。。。就是为了这个;
Lambda 表达式是 Java 8 引入的一项重要特性,它通过简化函数式接口的实现,使代码更加简洁和易读。Lambda 表达式广泛应用于集合遍历、Stream API、回调函数等场景。掌握 Lambda 表达式及其相关特性(如方法引用、函数式接口),可以显著提升 Java 开发效率和代码质量。