引言:什么是Lambda表达式?
Lambda表达式是Java 8引入的一种简洁的匿名函数语法。它允许我们将函数作为参数传递给方法,或者把代码当作数据来处理。
Lambda表达式的主要作用:
- 简化代码:减少匿名类的模板代码
- 函数式编程:支持函数作为一等公民
- 并行处理:为Stream API提供基础
函数式接口
函数式接口是只包含一个抽象方法的接口。Lambda表达式只能用于函数式接口。
常见的函数式接口
| 接口 | 抽象方法 | 说明 |
|---|---|---|
| Runnable | void run() | 无参数无返回值 |
| Supplier<T> | T get() | 无参数返回T |
| Consumer<T> | void accept(T t) | 消费T,无返回值 |
| Function<T,R> | R apply(T t) | 输入T返回R |
| Predicate<T> | boolean test(T t) | 判断T返回boolean |
Lambda语法
完整语法
(参数列表) -> { 方法体 }
语法简化规则
// 完整语法
Runnable r1 = () -> { System.out.println("Hello"); };
// 省略花括号(单行语句)
Runnable r2 = () -> System.out.println("Hello");
// 有参数
Comparator c1 = (String a, String b) -> { return a.compareTo(b); };
// 类型推断(省略参数类型)
Comparator c2 = (a, b) -> a.compareTo(b);
// 单个参数(省略括号)
Consumer c3 = s -> System.out.println(s);
方法引用
方法引用是Lambda表达式的简化写法,当Lambda表达式只是调用一个已有方法时使用。
方法引用的四种形式
// 1. 静态方法引用:ClassName::staticMethod
Function f1 = String::valueOf;
// 2. 实例方法引用:instance::method
String str = "Hello";
Supplier f2 = str::length;
// 3. 对象方法引用:ClassName::instanceMethod
Consumer f3 = System.out::println;
// 4. 构造方法引用:ClassName::new
Supplier f4 = ArrayList::new;
Stream API
Stream API是Java 8提供的处理集合的强大工具,支持函数式操作。
创建Stream
import java.util.stream.*;
import java.util.*;
// 从集合创建
List list = Arrays.asList("a", "b", "c");
Stream stream1 = list.stream();
// 从数组创建
String[] arr = {"x", "y", "z"};
Stream stream2 = Arrays.stream(arr);
// 直接创建
Stream stream3 = Stream.of(1, 2, 3);
常用操作
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// filter:过滤
List evens = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// map:转换
List squares = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
// sorted:排序
List sorted = numbers.stream()
.sorted()
.collect(Collectors.toList());
// limit:限制数量
List first3 = numbers.stream()
.limit(3)
.collect(Collectors.toList());
// distinct:去重
List distinct = numbers.stream()
.distinct()
.collect(Collectors.toList());
终端操作
List names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// forEach:遍历
names.stream().forEach(name -> System.out.println(name));
// collect:收集到集合
List list = names.stream().collect(Collectors.toList());
Set set = names.stream().collect(Collectors.toSet());
// count:计数
long count = names.stream().filter(n -> n.length() > 3).count();
// anyMatch/allMatch/noneMatch:匹配
boolean anyLong = names.stream().anyMatch(n -> n.length() > 5);
boolean allLong = names.stream().allMatch(n -> n.length() > 3);
boolean noneShort = names.stream().noneMatch(n -> n.length() < 2);
// reduce:聚合
List nums = Arrays.asList(1, 2, 3, 4, 5);
int sum = nums.stream().reduce(0, (a, b) -> a + b);
// findFirst/findAny:查找
Optional first = names.stream().findFirst();
实战练习
练习:处理学生列表
import java.util.*;
import java.util.stream.*;
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public int getScore() { return score; }
}
List students = Arrays.asList(
new Student("张三", 85),
new Student("李四", 92),
new Student("王五", 78),
new Student("赵六", 95)
);
// 找出成绩大于80的学生姓名
List topStudents = students.stream()
.filter(s -> s.getScore() > 80)
.map(Student::getName)
.collect(Collectors.toList());
System.out.println("成绩大于80的学生: " + topStudents);
// 计算平均分
double avgScore = students.stream()
.mapToInt(Student::getScore)
.average()
.orElse(0);
System.out.println("平均分: " + avgScore);
小结
- Lambda表达式:
(参数) -> { 方法体 },简化匿名类 - 函数式接口:只有一个抽象方法的接口
- 方法引用:
ClassName::method,进一步简化Lambda - Stream API:函数式处理集合,支持filter、map、sorted等操作
- Stream操作分为中间操作和终端操作
☕ Java 在线代码编辑器
📝 运行结果