Java Lambda 表达式深度解析

 更新时间:2026年04月24日 09:43:36   作者:代码or搬砖  
本文介绍了Java 8中的Lambda表达式,详细介绍了方法引用、Stream API与Lambda在集合操作中的应用及在MyBatis Plus中的应用,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

一、Lambda 表达式基础

1、什么是 Lambda 表达式

Lambda 表达式是 Java 8 引入的函数式编程特性,用于简化匿名内部类的写法。
Lambda 表达式本质上是一个匿名函数(没有名字的函数)。你可以把它理解为一小段可以传递的、即用即写的代码。

它的主要目的是为了简化代码,尤其是在需要使用匿名内部类的场景下,能让代码变得非常简洁、清晰。

2、基本语法

(parameters) -> expression
// 或
(parameters) -> { statements; }

二、Lambda 表达式的演变

1、 匿名内部类 → Lambda

// 传统匿名内部类
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello World");
    }
};
// Lambda 表达式
Runnable runnable = () -> System.out.println("Hello World");

2、各种形式的 Lambda

// 1. 无参数,无返回值
() -> System.out.println("Hello");
// 2. 一个参数,无返回值
(x) -> System.out.println(x);
x -> System.out.println(x);  // 括号可选
// 3. 多个参数,有返回值
(int x, int y) -> x + y;
(x, y) -> x + y;  // 类型推断
// 4. 复杂逻辑,需要代码块
(x, y) -> {
    int result = x + y;
    System.out.println("结果: " + result);
    return result;
}

三、函数式接口

1、什么是函数式接口

只有一个抽象方法的接口,可以用作 Lambda 表达式的类型。

2、Java 内置的常用函数式接口

1. Runnable - “执行一个动作”

作用:只做事,不要参数,不返回结果

// 定义:无参无返回值
Runnable r = () -> System.out.println("Running");
// 使用场景:线程任务、简单的代码块执行
r.run(); // 输出 "Running"
// 实际例子
new Thread(() -> System.out.println("在新线程中运行")).start();
// 相当于:执行一段代码块
() -> {
    System.out.println("第一件事");
    System.out.println("第二件事");
}

2. Consumer - “消费一个数据”

作用:吃进一个数据,消化掉(处理),不吐出来(不返回)

// 定义:消费一个参数,无返回值
Consumer<String> consumer = s -> System.out.println(s);
// 使用:接受数据并处理
consumer.accept("Hello World"); // 输出 "Hello World"
// 实际例子
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println("你好," + name));
// 输出:
// 你好,Alice
// 你好,Bob  
// 你好,Charlie
// 相当于:处理接收到的数据
(数据) -> {
    // 处理这个数据
    // 但不返回任何结果
}

3. Supplier - “提供一个数据”

作用:不吃饭(不要参数),只吐奶(返回值)

// 定义:无参数,返回一个值
Supplier<String> supplier = () -> "Hello";
// 使用:获取数据
String result = supplier.get(); // result = "Hello"
// 实际例子
Supplier<Double> randomSupplier = () -> Math.random();
Supplier<LocalDateTime> timeSupplier = () -> LocalDateTime.now();
System.out.println(randomSupplier.get()); // 输出随机数,如 0.12345
System.out.println(timeSupplier.get());   // 输出当前时间
// 相当于:一个数据工厂
() -> {
    return 产生的数据;
}

4. Function<T, R> - “转换数据”

作用:吃进T类型,吐出R类型(数据转换)

// 定义:接受T参数,返回R结果
Function<String, Integer> function = s -> s.length();
// 使用:数据转换
int length = function.apply("Hello"); // length = 5
// 实际例子
Function<String, String> toUpperCase = s -> s.toUpperCase();
Function<Integer, String> intToHex = i -> Integer.toHexString(i);
System.out.println(toUpperCase.apply("hello")); // 输出 "HELLO"
System.out.println(intToHex.apply(255));        // 输出 "ff"
// 相当于:数据加工厂
(输入数据) -> {
    return 加工后的数据;
}

5. Predicate - “判断条件”

作用:吃进数据,回答"是"或"否"

// 定义:接受T参数,返回boolean
Predicate<String> predicate = s -> s.isEmpty();
// 使用:条件判断
boolean result = predicate.test("");    // result = true
boolean result2 = predicate.test("Hi"); // result2 = false
// 实际例子
Predicate<String> isLongWord = s -> s.length() > 5;
Predicate<Integer> isEven = n -> n % 2 == 0;
List<String> words = Arrays.asList("apple", "banana", "cat", "elephant");
words.stream()
     .filter(isLongWord)  // 过滤出长度>5的单词
     .forEach(System.out::println);
// 输出:banana, elephant
// 相当于:条件检查器
(数据) -> {
    return 数据是否符合条件;
}

四、方法引用

1、方法引用的四种形式

// 1. 静态方法引用
Function<String, Integer> parser = Integer::parseInt;
// 2. 实例方法引用
String str = "Hello";
Supplier<Integer> lengthSupplier = str::length;
// 3. 任意对象的实例方法引用
Function<String, String> upperCase = String::toUpperCase;
// 4. 构造方法引用
Supplier<List<String>> listSupplier = ArrayList::new;

2、方法引用示例

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);
numbers.stream()
       .map(String::valueOf)  // 静态方法引用
       .forEach(System.out::println);

五、Stream API 与 Lambda

1、Stream 基础操作

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 过滤
List<String> result = names.stream()
    .filter(name -> name.length() > 3)      // Predicate
    .map(String::toUpperCase)               // Function
    .sorted()                               // Comparator
    .collect(Collectors.toList());          // Collector

2、常用 Stream 操作

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 过滤偶数,平方,然后求和
int sum = numbers.stream()
    .filter(n -> n % 2 == 0)           // 过滤偶数
    .map(n -> n * n)                   // 平方
    .reduce(0, Integer::sum);          // 求和
// 分组操作
Map<String, List<Person>> peopleByCity = people.stream()
    .collect(Collectors.groupingBy(Person::getCity));  // 方法引用

六、在集合操作中的应用

1、List 操作

List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// 遍历
list.forEach(item -> System.out.println(item));
// 排序
list.sort((a, b) -> a.compareTo(b));
list.sort(String::compareTo);  // 方法引用
// 过滤
List<String> filtered = list.stream()
    .filter(s -> s.startsWith("A"))
    .collect(Collectors.toList());

2、Map 操作

Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
map.put("Charlie", 35);
// 遍历
map.forEach((name, age) -> 
    System.out.println(name + ": " + age));
// 转换
Map<String, String> nameLength = map.entrySet().stream()
    .collect(Collectors.toMap(
        Map.Entry::getKey,                   // 键
        entry -> String.valueOf(entry.getValue())  // 值
    ));

七、在 MyBatis-Plus 中的应用

1、LambdaQueryWrapper

// 实体类属性引用
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")           // 方法引用
      .gt(User::getAge, 18)                // Lambda
      .like(User::getEmail, "@gmail.com");
// 等价于:WHERE name = '张三' AND age > 18 AND email LIKE '%@gmail.com%'

2、复杂条件构建

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
// 条件分组
wrapper.and(w -> w
    .eq(User::getStatus, 1)
    .or()
    .eq(User::getStatus, 2)
).or(w -> w
    .gt(User::getAge, 60)
    .lt(User::getAge, 18)
);
// 等价于:WHERE (status = 1 OR status = 2) OR (age > 60 OR age < 18)

到此这篇关于Java Lambda 表达式深度解析的文章就介绍到这了,更多相关Java Lambda 表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java代码执行顺序——类的初始化场景

    Java代码执行顺序——类的初始化场景

    这篇文章主要为大家介绍了Java代码执行顺序类的初始化场景实例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Mybatis动态SQL之IF语句详解

    Mybatis动态SQL之IF语句详解

    这篇文章主要给大家介绍了关于Mybatis动态SQL之IF语句的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • springboot yml配置文件定义list集合、数组和map以及使用中的错误

    springboot yml配置文件定义list集合、数组和map以及使用中的错误

    这篇文章主要介绍了springboot yml配置文件定义list集合、数组和map以及使用中遇到的错误问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java常用字符串方法小结

    Java常用字符串方法小结

    字符串变量是Java与C语言的一大不同之处。Java之中的 String 类和 Stringbuffer 类提供了大量的对字符串操作的方法。String 类适合处理较小的字符串,而Stringbuffer类适合处理大量字符串
    2017-04-04
  •  Spring 中 Bean 的生命周期详解

     Spring 中 Bean 的生命周期详解

    这篇文章主要介绍了Spring中Bean的生命周期详解,Java中的公共类称之为Bean或Java Bean,而Spring中的Bean指的是将对象的生命周期
    2022-09-09
  • Java多线程状态及方法实例解析

    Java多线程状态及方法实例解析

    这篇文章主要介绍了Java多线程状态及方法实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java数据结构(线性表)详解

    Java数据结构(线性表)详解

    本文主要介绍了Java数据结构(线性表)的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • 使用spring-cache一行代码解决缓存击穿问题

    使用spring-cache一行代码解决缓存击穿问题

    本文主要介绍了使用spring-cache一行代码解决缓存击穿问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • SpringBoot整合WebSocket的客户端和服务端的实现代码

    SpringBoot整合WebSocket的客户端和服务端的实现代码

    这篇文章主要介绍了SpringBoot整合WebSocket的客户端和服务端的实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Java设计模式之抽象工厂模式(Abstract Factory)

    Java设计模式之抽象工厂模式(Abstract Factory)

    这篇文章主要为大家详细介绍了Java设计模式之抽象工厂模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论