掌握函数式编程基础、方法引用、Stream API和实际应用案例
Lambda表达式是Java 8引入的重要特性,它允许我们以更简洁的方式表示匿名函数。Lambda表达式的核心思想是将函数作为一等公民,支持函数式编程范式。
// 基本格式
(parameters) -> expression
// 或者
(parameters) -> { statements; }
// 示例
(x, y) -> x + y
() -> System.out.println("Hello")
x -> x * 2
// 传统匿名内部类
Runnable oldWay = new Runnable() {
@Override
public void run() {
System.out.println("Hello World");
}
};
// Lambda表达式
Runnable newWay = () -> System.out.println("Hello World");
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}
// 使用Lambda表达式
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
int result1 = add.calculate(5, 3); // 8
int result2 = multiply.calculate(5, 3); // 15
Java 8在java.util.function包中提供了许多预定义的函数式接口,这些接口涵盖了大部分常见的使用场景。
接口名称 | 方法签名 | 用途 | 示例 |
---|---|---|---|
Predicate<T> |
boolean test(T t) |
断言型接口,用于条件判断 | x -> x > 0 |
Function<T,R> |
R apply(T t) |
函数型接口,用于类型转换 | s -> s.length() |
Consumer<T> |
void accept(T t) |
消费型接口,用于处理数据 | s -> System.out.println(s) |
Supplier<T> |
T get() |
供给型接口,用于生产数据 | () -> Math.random() |
UnaryOperator<T> |
T apply(T t) |
一元操作符,输入输出同类型 | x -> x * x |
BinaryOperator<T> |
T apply(T t1, T t2) |
二元操作符,两个输入一个输出 | (a, b) -> a + b |
方法引用是Lambda表达式的简化形式,当Lambda表达式只是调用一个已存在的方法时,可以使用方法引用来进一步简化代码。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Lambda表达式
names.forEach(name -> System.out.println(name));
// 方法引用
names.forEach(System.out::println);
// 静态方法引用
List<Integer> numbers = Arrays.asList("1", "2", "3")
.stream()
.map(Integer::parseInt) // 等价于 s -> Integer.parseInt(s)
.collect(Collectors.toList());
// 构造器引用
Supplier<List<String>> listSupplier = ArrayList::new;
List<String> newList = listSupplier.get();
Stream API是Java 8的另一个重要特性,它与Lambda表达式完美结合,提供了强大的数据处理能力。Stream支持函数式编程风格的操作,如过滤、映射、归约等。
List<Person> people = Arrays.asList(
new Person("Alice", 25, "Engineer"),
new Person("Bob", 30, "Manager"),
new Person("Charlie", 35, "Engineer"),
new Person("David", 28, "Designer")
);
// 过滤、映射、收集
List<String> engineerNames = people.stream()
.filter(p -> "Engineer".equals(p.getJob())) // 过滤工程师
.map(Person::getName) // 提取姓名
.collect(Collectors.toList()); // 收集结果
// 分组统计
Map<String, Long> jobCounts = people.stream()
.collect(Collectors.groupingBy(
Person::getJob,
Collectors.counting()
));
// 查找最年长的人
Optional<Person> oldest = people.stream()
.max(Comparator.comparing(Person::getAge));
// 计算平均年龄
Double averageAge = people.stream()
.collect(Collectors.averagingInt(Person::getAge));