1365 字
约 4 分钟
9
Java Lambda表达式
无标签

第63章 Java Lambda表达式

面包屑导航 章节头部 学习目标

学习目标

  • 理解Lambda表达式的语法和基本概念
  • 掌握函数式接口的定义和使用
  • 学会使用方法引用简化代码
  • 熟练运用Stream API进行数据处理
  • 了解Lambda表达式的性能特点和最佳实践
  • 掌握函数式编程思想在Java中的应用

Lambda表达式基础

Lambda表达式基础

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
  • 只能有一个抽象方法
  • 可以有默认方法和静态方法
  • @FunctionalInterface注解可选但推荐
  • Lambda表达式的目标类型

常用函数式接口

常用函数式接口

Java 8在java.util.function包中提供了许多预定义的函数式接口,这些接口涵盖了大部分常见的使用场景。

接口名称 方法签名 用途 示例
Predicate boolean test(T t) 断言型接口,用于条件判断 x -> x > 0
Function<T,R> R apply(T t) 函数型接口,用于类型转换 s -> s.length()
Consumer void accept(T t) 消费型接口,用于处理数据 s -> System.out.println(s)
Supplier T get() 供给型接口,用于生产数据 () -> Math.random()
UnaryOperator T apply(T t) 一元操作符,输入输出同类型 x -> x * x
BinaryOperator T apply(T t1, T t2) 二元操作符,两个输入一个输出 (a, b) -> a + b

方法引用

方法引用详解

方法引用是Lambda表达式的简化形式,当Lambda表达式只是调用一个已存在的方法时,可以使用方法引用来进一步简化代码。

四种方法引用类型静态方法引用:ClassName::staticMethod实例方法引用:ClassName::instanceMethod特定对象的实例方法引用:object::instanceMethod构造器引用:ClassName::new

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

Stream API应用

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));

最佳实践

Lambda表达式最佳实践

推荐做法

  • 保持Lambda表达式简短,通常不超过3行
  • 使用方法引用替代简单的Lambda表达式
  • 为复杂的Lambda表达式提取为方法
  • 优先使用标准函数式接口
  • 避免在Lambda中修改外部变量
  • 使用并行流时注意线程安全

避免做法

  • 不要在Lambda中使用过多的嵌套
  • 避免在Lambda中抛出检查异常
  • 不要滥用并行流,考虑性能开销
  • 避免在Lambda中进行复杂的业务逻辑
  • 不要忽略Stream的惰性求值特性
  • 避免重复创建相同的Lambda表达式

章节总结

章节总结

  • Lambda表达式是Java 8引入的重要特性,支持函数式编程
  • 函数式接口是Lambda表达式的基础,只能有一个抽象方法
  • 方法引用是Lambda表达式的简化形式,提高代码可读性
  • Stream API与Lambda表达式结合,提供强大的数据处理能力
  • 合理使用Lambda表达式可以显著提高代码的简洁性和可读性
  • 掌握函数式编程思想有助于编写更优雅的Java代码

导航链接 上一章:Java多线程编程 章节测验 下一章:Java网络编程

Java Lambda表达式
https://clxhxhhr.top/posts/2764/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。