Java-Lambda 表达式

Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁的方式来表示匿名函数。Lambda 表达式主要用于简化函数式接口的实现,使代码更加简洁和易读。以下是关于 Lambda 表达式的详细阐述:


1. Lambda 表达式的基本语法

Lambda 表达式的语法如下:

java 复制代码
(parameter_list) -> { 代码块 }
  • parameter_list:参数列表,可以包含零个或多个参数,参数类型可以省略(由编译器自动推断)。
  • ->:Lambda 操作符,将参数列表与 Lambda 主体分隔开。
  • 代码块:Lambda 主体,包含实现函数式接口的代码。如果只有一行代码,可以省略 {} 和 return 语句。
示例:
java 复制代码
// 无参数
() -> System.out.println("Hello, World!");

// 单个参数
(x) -> x * x;

// 多个参数
(x, y) -> x + y;

// 带代码块
(x, y) -> {
    int sum = x + y;
    return sum;
};

2. 函数式接口

Lambda 表达式的核心是函数式接口(Functional Interface)。函数式接口是指 仅包含一个抽象方法 的接口。Java 提供了 @FunctionalInterface 注解来标记函数式接口。

常见的函数式接口:
  • Runnable:void run()
  • Consumer<T>:void accept(T t)
  • Supplier<T>:T get()
  • Function<T, R>:R apply(T t)
  • Predicate<T>:boolean test(T t)
示例:
java 复制代码
@FunctionalInterface
interface MyInterface {
    void doSomething();
}

// 使用 Lambda 表达式实现函数式接口
MyInterface myLambda = () -> System.out.println("Doing something");
myLambda.doSomething();

好好体会一下,lambda式是一个函数,他赋值给一个接口变量,那么这个接口一定要有一个抽象方法去实现,正好把lambda的这个函数赋值给这个未被重写的抽象类;而且这个接口一定只能有一个未实现方法,为什么呢,因为如果有多个,谁也分不清楚给哪个方法;有点意思!


3. Lambda 表达式的使用场景

(1) 简化匿名内部类

Lambda 表达式可以替代匿名内部类,使代码更简洁。

java 复制代码
// 传统匿名内部类
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, World!");
    }
};

// 使用 Lambda 表达式
Runnable r2 = () -> System.out.println("Hello, World!");

注意:以上代码中Runnable 就只是一个普通的函数式接口,只是起到举例子的效果,可以替换成自定义函数式接口

(2) 遍历集合

Lambda 表达式结合 forEach() 方法可以简化集合的遍历操作。

java 复制代码
List<String> list = Arrays.asList("Apple", "Banana", "Orange");

// 传统遍历
for (String s : list) {
    System.out.println(s);
}

// 使用 Lambda 表达式
list.forEach(s -> System.out.println(s));
(3) 作为方法参数

Lambda 表达式可以作为方法参数传递,特别适合用于需要回调函数的场景。

java 复制代码
public static void processList(List<String> list, Consumer<String> consumer) {
    for (String s : list) {
        consumer.accept(s);
    }
}

// 调用方法
processList(list, s -> System.out.println(s));
(4) 结合 Stream API

Lambda 表达式与 Stream API 结合,可以实现强大的数据处理功能,如过滤、映射、排序等。

java 复制代码
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange", "Mango");

// 过滤长度大于 5 的字符串
List<String> filtered = fruits.stream()
                              .filter(s -> s.length() > 5)
                              .collect(Collectors.toList());

// 将字符串转换为大写
List<String> upperCase = fruits.stream()
                               .map(s -> s.toUpperCase())
                               .collect(Collectors.toList());

4. Lambda 表达式的变量作用域

Lambda 表达式可以访问外部的局部变量、实例变量和静态变量,但有如下限制:

  1. 局部变量 :Lambda 表达式访问的局部变量必须是 final 或实际上是 final 的(即不可变)。
  2. 实例变量和静态变量:Lambda 表达式可以访问并修改实例变量和静态变量。
示例:
java 复制代码
int num = 10; // 局部变量
Runnable r = () -> System.out.println(num); // num 必须是 final 或 effectively final

// 错误示例
int num2 = 20;
num2 = 30; // 修改 num2
Runnable r2 = () -> System.out.println(num2); // 编译错误:num2 必须是 final

5. 方法引用

方法引用是 Lambda 表达式的一种简化形式,用于直接引用已有的方法。方法引用的语法如下:

java 复制代码
类名::方法名
方法引用的四种形式:
  1. 静态方法引用 :ClassName::staticMethod
  2. 实例方法引用 :instance::instanceMethod
  3. 特定类型的任意对象方法引用 :ClassName::instanceMethod
  4. 构造方法引用 :ClassName::new
示例:
java 复制代码
List<String> list = Arrays.asList("Apple", "Banana", "Orange");

// 使用 Lambda 表达式
list.forEach(s -> System.out.println(s));

// 使用方法引用
list.forEach(System.out::println);

好好理解上面的例子,还挺有意思,但是挺无聊;

感觉就是,有一个类他有很多方法,但是我就想要他的其中一个方法。。。。就是为了这个;


6. 注意事项

  1. 简洁性:Lambda 表达式应尽量保持简洁,避免过于复杂的逻辑。
  2. 可读性:如果 Lambda 表达式过长或逻辑复杂,应考虑使用命名方法代替。
  3. 性能:Lambda 表达式的性能与传统方式相当,但在某些情况下可能会有轻微的开销。

总结

Lambda 表达式是 Java 8 引入的一项重要特性,它通过简化函数式接口的实现,使代码更加简洁和易读。Lambda 表达式广泛应用于集合遍历、Stream API、回调函数等场景。掌握 Lambda 表达式及其相关特性(如方法引用、函数式接口),可以显著提升 Java 开发效率和代码质量。

相关推荐
后台模板学习6 分钟前
Go Web开发中任务调度框架的源码解析与高可用实现方案
开发语言·后端·golang
西瓜拿铁好喝9 分钟前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
学长毕设11 分钟前
基于SpringBoot的校园礼服租赁系统的设计与实现
java·spring boot·后端
明天也要努力学习17 分钟前
深入理解 JVM 垃圾回收(GC)
java·jvm
xiaoye-duck20 分钟前
《C++ 项目:手写大模型接入 SDK》DeepSeek接口设计(上):初始化和全量响应
开发语言·网络·c++·语言模型
golang学习记25 分钟前
IDEA 断点调试技巧:拖拽
java·ide·intellij-idea
fpcc25 分钟前
跟我学c++中级篇—streambuf在glog中的应用分析
开发语言·c++
Sayai26 分钟前
Flink 日志解析任务性能优化实战:正则/Grok 预编译、Guava 缓存权重陷阱与 ES 写入隔离
java·大数据·性能优化·flink·实时计算
吾与谁归in27 分钟前
C#脚本工具,支持智能提示自动补全(WPF + Roslyn + AvalonEdit)
开发语言·c#·wpf
计算机毕设定制辅导-无忧学长28 分钟前
《基于物品协同过滤的闲置书换购微信小程序设计开发》
java·vue.js·spring boot·微信小程序·uniapp·闲置书换购微信小程序·物品协同过滤算法