Java 8 Lambda 表达式使用说明与案例
Lambda 表达式是 Java 8 最重要的新特性之一,它使代码更加简洁,并支持函数式编程风格。
一、Lambda 表达式基础
1. 语法结构
(parameters) -> expression
或
(parameters) -> { statements; }
2. 基本特征
- 可选类型声明:不需要声明参数类型,编译器可以统一识别
- 可选参数圆括号:一个参数无需圆括号,多个参数需要
- 可选大括号:表达式主体只有一条语句时不需要大括号
- 可选return关键字:表达式主体只有一条返回语句时,编译器会自动返回
3. 简单示例
// 1. 无参数,返回5
() -> 5
// 2. 接收参数x,返回x*2
x -> x * 2
// 3. 接收两个参数,返回它们的和
(int x, int y) -> x + y
// 4. 接收字符串并打印
(String s) -> System.out.println(s)
// 5. 接收两个参数,比较大小
(String s1, String s2) -> s1.compareTo(s2)
二、Lambda 使用案例
1. 集合遍历
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 传统方式
for (String name : names) {
System.out.println(name);
}
// Lambda方式
names.forEach(name -> System.out.println(name));
// 方法引用方式
names.forEach(System.out::println);
2. 线程创建
// 传统方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("传统线程");
}
}).start();
// Lambda方式
new Thread(() -> System.out.println("Lambda线程")).start();
3. 集合排序
List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript");
// 传统方式
Collections.sort(languages, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
// Lambda方式
Collections.sort(languages, (o1, o2) -> o1.compareTo(o2));
// 更简洁的方式
languages.sort((o1, o2) -> o1.compareTo(o2));
4. 过滤集合
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 过滤偶数
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
5. 映射操作
List<String> words = Arrays.asList("hello", "world");
// 将每个单词转为大写
List<String> upperCaseWords = words.stream()
.map(word -> word.toUpperCase())
.collect(Collectors.toList());
// 方法引用方式
List<String> upperCaseWords = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
6. 函数式接口使用
// 自定义函数式接口
@FunctionalInterface
interface GreetingService {
void sayMessage(String message);
}
// 使用Lambda实现
GreetingService greetService1 = message -> System.out.println("Hello " + message);
greetService1.sayMessage("World");
GreetingService greetService2 = message -> System.out.println("你好 " + message);
greetService2.sayMessage("世界");
三、常用函数式接口
Java 8 在 java.util.function
包中提供了许多内置函数式接口:
Predicate - 断言型接口
Predicate<String> lengthCheck = s -> s.length() > 5; boolean result = lengthCheck.test("HelloWorld"); // true
Function<T,R> - 函数型接口
Function<String, Integer> lengthFunction = s -> s.length(); int len = lengthFunction.apply("Java"); // 4
Consumer - 消费型接口
Consumer<String> printer = s -> System.out.println(s); printer.accept("Hello Lambda"); // 输出 Hello Lambda
Supplier - 供给型接口
Supplier<Double> randomSupplier = () -> Math.random(); double randomValue = randomSupplier.get();
四、Lambda 表达式注意事项
- Lambda 表达式只能用于函数式接口(只有一个抽象方法的接口)
- Lambda 表达式中的局部变量必须是 final 或 effectively final
- Lambda 表达式没有自己的作用域,不能覆盖外部作用域的变量
- 在 Lambda 表达式中,this 关键字指的是包含它的外部类实例
五、方法引用
Lambda 表达式的简写形式,有四种类型:
静态方法引用 -
ClassName::staticMethod
Function<String, Integer> parser = Integer::parseInt;
实例方法引用 -
instance::method
String str = "Hello"; Supplier<Integer> lengthSupplier = str::length;
任意对象的实例方法引用 -
ClassName::method
List<String> names = Arrays.asList("Alice", "Bob"); names.forEach(System.out::println);
构造方法引用 -
ClassName::new
Supplier<List<String>> listSupplier = ArrayList::new;
Lambda 表达式极大地简化了 Java 代码,特别是在集合操作和并发编程中,使代码更加简洁和易读。