知识点:Java 中的 Lambda 表达式

一、Lambda 表达式是什么

Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁的方式来表示可传递给方法或存储在变量中的代码块。简单来说,Lambda 表达式允许我们用更紧凑的语法表示匿名函数,让代码更加简洁、易读。

二、Lambda 表达式的基本语法

Lambda 表达式的基本语法形式为:(parameters) -> expression 或者 (parameters) -> { statements; }。其中,parameters 是参数列表,可以为空;-> 是 Lambda 运算符,用于分隔参数列表和表达式或语句块;expression 是一个表达式,会被求值并返回;{ statements; } 是一个语句块,包含多条语句。

三、使用场景

(一)作为函数式接口的实例

函数式接口是指只包含一个抽象方法的接口。Java 8 中提供了许多函数式接口,如 Runnable、Comparator 等。Lambda 表达式可以很方便地作为这些函数式接口的实例。

auto 复制代码
// 使用匿名内部类实现 Runnable 接口
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("使用匿名内部类实现 Runnable");
    }
};

// 使用 Lambda 表达式实现 Runnable 接口
Runnable r2 = () -> System.out.println("使用 Lambda 表达式实现 Runnable");

public class LambdaRunnableExample {
    public static void main(String[] args) {
        new Thread(r1).start();
        new Thread(r2).start();
    }
}

在这个例子中,r1 使用匿名内部类实现 Runnable 接口,r2 使用 Lambda 表达式实现 Runnable 接口,Lambda 表达式的语法更加简洁。

(二)作为方法参数

许多 Java 8 的 API 方法接受函数式接口作为参数,这时可以直接传递 Lambda 表达式。例如,Collections.sort 方法可以接受一个 Comparator 接口的实例来定义排序规则。

auto 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class LambdaComparatorExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(3);
        numbers.add(1);
        numbers.add(2);

        // 使用 Lambda 表达式作为 Comparator 参数进行排序
        Collections.sort(numbers, (a, b) -> a - b);

        System.out.println(numbers); 
    }
}

这里 (a, b) -> a - b 是一个 Lambda 表达式,作为 Comparator 的实现传递给 Collections.sort 方法,定义了升序排序的规则。

(三)与 Stream API 结合使用

Stream API 是 Java 8 中用于处理集合数据的强大工具,Lambda 表达式与 Stream API 结合可以实现高效、简洁的数据处理。

auto 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class LambdaStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 使用 Stream API 和 Lambda 表达式进行数据处理
        List<Integer> squaredNumbers = numbers.stream()
              .map(n -> n * n)
              .collect(Collectors.toList());

        System.out.println(squaredNumbers); 
    }
}

在这个例子中,n -> n * n 是一个 Lambda 表达式,作为 map 方法的参数,对 Stream 中的每个元素进行平方操作。

四、自定义 Lambda

除了使用 Java 内置的函数式接口,我们还可以自定义函数式接口,并使用 Lambda 表达式来实现它。

(一)自定义函数式接口

auto 复制代码
@FunctionalInterface
interface StringTransformer {
    String transform(String input);
}

这里使用 @FunctionalInterface 注解标识这是一个函数式接口,它只包含一个抽象方法 transform,该方法接受一个 String 类型的参数并返回一个 String。

(二)使用自定义函数式接口和 Lambda 表达式

auto 复制代码
public class CustomLambdaExample {
    public static void main(String[] args) {
        StringTransformer toUpperCaseTransformer = input -> input.toUpperCase();
        StringTransformer reverseTransformer = input -> {
            StringBuilder sb = new StringBuilder(input);
            return sb.reverse().toString();
        };

        String originalString = "hello";
        String upperCaseString = applyTransformer(originalString, toUpperCaseTransformer);
        String reversedString = applyTransformer(originalString, reverseTransformer);

        System.out.println("转大写: " + upperCaseString);
        System.out.println("反转: " + reversedString);
    }

    public static String applyTransformer(String input, StringTransformer transformer) {
        return transformer.transform(input);
    }
}

在上述代码中,我们定义了两个 Lambda 表达式来实现 StringTransformer 接口。toUpperCaseTransformer 将字符串转换为大写,reverseTransformer 将字符串反转。applyTransformer 方法接受一个字符串和一个 StringTransformer 实例,通过调用 transform 方法对字符串进行相应的转换操作。

通过自定义 Lambda,我们可以根据具体的业务需求灵活地定义函数式接口,并使用简洁的 Lambda 表达式来实现其功能,进一步提升代码的灵活性和简洁性。Lambda 表达式为 Java 编程带来了函数式编程的风格,使得代码更加简洁、灵活,提高了开发效率。掌握 Lambda 表达式对于深入学习和使用 Java 8 及后续版本的新特性至关重要。

相关推荐
zhoujungis3 分钟前
登录态 1 小时就掉?Django + Vue 双 Token 认证实战 | 尘世栈帧
后端
Félix2518 分钟前
Nacos学习笔记(SpringBoot/SpringCloud)
java·spring boot·spring
文丑颜不良啊13 分钟前
LeetCode1581~1600题目解析
java·leetcode
香蕉大香蕉(06敬畏市场)14 分钟前
MySQL 单点详解(06)
java·数据库·mysql·博客·实习
武子康22 分钟前
同一台 ESP32,GSM 能消回声,VoIP 为什么不行?
人工智能·后端·agent
用户693717500138426 分钟前
AI 能写代码,但工程架构还是应该由人来定
前端·后端
lqbzlll27 分钟前
Spring Boot 开启虚拟线程后接口反而变慢了?4 个排查方向和对应修法
java·spring boot·后端
七夜zippoe31 分钟前
LangChain4j vs Spring AI:Java AI 框架怎么选(对比表)
java·人工智能·spring·ai·langchain4j
悠仁さん37 分钟前
【C++】set map 使用
java·前端·c++
回家路上绕了弯40 分钟前
让 AI 成为团队的共同能力
后端