Java 中的 Lambda 表达式和 JDK 21 新特性详解
前言
Java 8 引入了 Lambda 表达式,极大地简化了代码编写,提高了开发效率。随着 JDK 21 的发布,Java 继续扩展和优化了 Lambda 表达式的功能,使其更加灵活和强大。本文将详细介绍 Java 中 Lambda 表达式的基本语法、类型推断、方法引用,并结合 JDK 21 的新特性,帮助读者更好地理解和使用这些功能。
1. Lambda 表达式的基本语法
Lambda 表达式是一种简洁的匿名函数表示法,其基本语法如下:
(parameters) -> expression
(parameters) -> { statements; }
1.1 无参、无返回值
Runnable runnable = () -> System.out.println("Hello, Lambda!");
runnable.run();
1.2 有参、无返回值
Consumer<String> consumer = (String s) -> System.out.println(s);
consumer.accept("Hello, World!");
1.3 有参、有返回值
Function<Integer, Integer> function = (Integer x) -> x * 2;
int result = function.apply(5);
System.out.println(result); // 输出 10
2. 类型推断
Lambda 表达式中的参数类型可以由编译器自动推断,因此通常可以省略参数类型。
Comparator<String> comparator = (a, b) -> a.compareTo(b);
3. 方法引用
方法引用是一种更简洁的表示 Lambda 表达式的方式,适用于已经有现成方法可以重用的情况。
3.1 引用对象的方法
User user = new User("Alice");
Consumer<String> consumer = user::sayHello;
consumer.accept("Bob");
3.2 引用类的静态方法
Comparator<Integer> comparator = Integer::compare;
3.3 引用类的实例方法
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort(String::compareToIgnoreCase);
3.4 构造器引用
Supplier<User> supplier = User::new;
User user = supplier.get();
4. JDK 21 的新特性
JDK 21 继续扩展和优化了 Lambda 表达式的功能,以下是一些值得关注的新特性。
4.1 类型安全的 Lambda 表达式
JDK 21 引入了类型安全的 Lambda 表达式支持,进一步简化了类型推断,使代码更加简洁。
List<String> list = Arrays.asList("apple", "banana", "orange");// 使用之前的 Lambda 表达式
list.stream().filter(s -> s.startsWith("a")).forEach(System.out::println);// 使用 JDK 21 的类型安全 Lambda 表达式,这里编译器可以更好地推断类型
list.stream().filter(s -> s.startsWith("a")).forEach(System.out::println);
4.2 默认方法的支持
在 JDK 8 中引入了接口中的默认方法,JDK 21 继续优化了这些功能,使得 Lambda 表达式可以更灵活地与默认方法结合使用。
@FunctionalInterface
interface Task {void perform();default void log() {System.out.println("Task performed");}
}public class Main {public static void main(String[] args) {Task task = () -> System.out.println("Performing task...");task.perform();task.log();}
}
5. 注意事项
5.1 函数式接口
Lambda 表达式只能用于函数式接口,即接口中只有一个抽象方法的接口。可以使用 @FunctionalInterface
注解来确保接口符合要求。
@FunctionalInterface
interface MyFunction {int apply(int x, int y);
}
5.2 方法引用的限制
方法引用中的方法必须与 Lambda 表达式的目标类型相匹配。如果方法签名不匹配,编译器会报错。
6. 示例代码
6.1 使用 Lambda 表达式进行排序
import java.util.Arrays;
import java.util.List;
import java.util.Comparator;public class Main {public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 使用 Lambda 表达式进行排序names.sort((a, b) -> a.compareTo(b));// 使用方法引用进行排序names.sort(String::compareTo);// 打印排序后的列表names.forEach(System.out::println);}
}
6.2 使用 Lambda 表达式进行过滤和映射
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class Main {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 过滤偶数并平方List<Integer> squaredEvenNumbers = numbers.stream().filter(n -> n % 2 == 0).map(n -> n * n).collect(Collectors.toList());// 打印结果squaredEvenNumbers.forEach(System.out::println);}
}
结论
JDK 21 中的 Lambda 表达式继续优化和完善,提供了更多的灵活性和简洁性。通过结合类型推断、方法引用和默认方法,可以编写出更加优雅和高效的代码。希望本文的介绍和示例能够帮助读者更好地理解和使用 Java 中的 Lambda 表达式和 JDK 21 的新特性。