Java-Lambda 表达式

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


1. Lambda 表达式的基本语法

Lambda 表达式的语法如下:

(parameter_list) -> { 代码块 }
  • parameter_list:参数列表,可以包含零个或多个参数,参数类型可以省略(由编译器自动推断)。
  • ->:Lambda 操作符,将参数列表与 Lambda 主体分隔开。
  • 代码块:Lambda 主体,包含实现函数式接口的代码。如果只有一行代码,可以省略 {}return 语句。
示例:
// 无参数
() -> 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 注解来标记函数式接口。

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

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

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


3. Lambda 表达式的使用场景

(1) 简化匿名内部类

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

// 传统匿名内部类
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() 方法可以简化集合的遍历操作。

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 表达式可以作为方法参数传递,特别适合用于需要回调函数的场景。

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 结合,可以实现强大的数据处理功能,如过滤、映射、排序等。

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 表达式可以访问并修改实例变量和静态变量。
示例:
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 表达式的一种简化形式,用于直接引用已有的方法。方法引用的语法如下:

类名::方法名
方法引用的四种形式:
  1. 静态方法引用ClassName::staticMethod
  2. 实例方法引用instance::instanceMethod
  3. 特定类型的任意对象方法引用ClassName::instanceMethod
  4. 构造方法引用ClassName::new
示例:
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 开发效率和代码质量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值