【java进阶】------ Lambda表达式

关于匿名内部类的详细知识点,请查阅《【java面向对象进阶】------内部类》

关于Array的排序规则请参考本文《【java常用API】----- Arrays》


1. 什么是函数式编程

在正式学习Lambda之前,我们需要先理解一种编程思想:函数式编程(Functional Programming)

  • 面向对象思想:强调"谁去做"。做事情必须先找一个对象,通过对象调用方法来完成。
  • 函数式思想:强调"做什么"。它忽略面向对象的复杂语法,只关注结果,不关注执行的对象是谁。

Lambda表达式正是函数式思想在Java中的具体体现。


2. Lambda表达式的标准格式

Lambda表达式是JDK 8引入的一种新语法形式,它的核心作用是简化匿名内部类的写法

2.1 标准语法结构

Lambda表达式的标准格式由三个部分组成:

java 复制代码
(参数列表) -> { 方法体代码 }
  • ():对应着接口中抽象方法的形参列表
  • ->:Lambda操作符(箭头操作符),是固定格式,表示指向。
  • {}:对应着接口中抽象方法的方法体

2.2 代码演变:从匿名内部类到Lambda

让我们通过Arrays.sort的降序排序案例,看看代码是如何演变的。

需求:对整数数组进行降序排序。

2.2.1 传统写法:匿名内部类

java 复制代码
Integer[] arr = {3, 1, 4, 2};

Arrays.sort(arr, new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
});

2.2.2 Lambda写法:简化后的代码

java 复制代码
Integer[] arr = {3, 1, 4, 2};

// Lambda完整格式
Arrays.sort(arr, (Integer o1, Integer o2) -> {
    return o2 - o1;
});

对比分析

  • 我们省略了new Comparator<>() { ... }这一大串模板代码。
  • 我们只保留了最核心的参数(o1, o2)和执行逻辑-> { return o2 - o1; }

3. Lambda表达式的前提条件

并不是所有的匿名内部类都能用Lambda表达式简化,必须满足以下前提:

  1. 必须是接口的匿名内部类
  2. 接口中只能有一个抽象方法

满足上述条件的接口,被称为函数式接口

💡 知识点:@FunctionalInterface

这是一个注解,用于检测一个接口是否是函数式接口。如果接口上有此注解,但包含多个抽象方法,编译器会报错。虽然不写这个注解也能运行,但为了代码的严谨性,建议在函数式接口上加上此注解。


4. Lambda表达式的省略写法

Lambda之所以流行,是因为它支持大量的语法省略。其核心原则只有一条:可推导,可省略。即编译器能根据上下文推导出类型的,都可以省略。

4.1 省略规则速查表

规则描述 示例(假设接口方法为 void run()int compare(...)
参数类型可省略 (Integer o1, Integer o2)(o1, o2)编译器根据泛型自动推断类型
单参数可省略括号 仅有一个参数省略了类型 ,则 () 可省略。例如:(e)e(若保留类型如 (String e),则括号不可省)
单行代码可省略大括号 若方法体仅有一行代码,{};return同时省略 。例如:(x, y) -> { return x + y; }(x, y) -> x + y

4.2 省略演示

让我们继续使用排序的例子,看看代码是如何一步步"瘦身"的。

场景 :对整数数组进行降序排序。

4.2.1 第一阶段:Lambda完整格式

java 复制代码
Arrays.sort(arr, (Integer o1, Integer o2) -> {
    return o2 - o1;
});

4.2.2 第二阶段:省略参数类型

编译器可以通过arr数组的类型推导出o1o2都是Integer类型。

java 复制代码
Arrays.sort(arr, (o1, o2) -> {
    return o2 - o1;
});

4.2.3 第三阶段:省略大括号、return和分号

因为方法体只有一行代码,我们可以将其简化为一行流式写法。

java 复制代码
// 最终形态
Arrays.sort(arr, (o1, o2) -> o2 - o1);

5. 实战练习:字符串长度排序

为了巩固Lambda的使用,我们来完成一个实际的小练习。

需求

  1. 定义一个字符串数组 {"a", "aaaa", "aaa", "aa"}
  2. 使用Arrays.sort进行排序。
  3. 排序规则 :按照字符串的长度进行降序排序(长的在前,短的在后)。

5.1 传统匿名内部类写法

java 复制代码
package com.example;
import java.util.Arrays;
import java.util.Comparator;

public class ArraysDemo {
    public static void main(String[] args) {
        String[] arr = {"a", "aaaa", "aaa", "aa"};

        Arrays.sort(arr, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // 按照长度比较:o2长度 - o1长度
                return o2.length() - o1.length();
            }
        });
        //输出结果:[aaaa, aaa, aa, a]
        System.out.println(Arrays.toString(arr));
    }
}

5.2 Lambda省略写法(推荐)

我们可以直接利用省略规则,将代码简化到最极致:

java 复制代码
package com.example;
import java.util.Arrays;

public class ArraysDemo {
    public static void main(String[] args) {
        String[] arr = {"a", "aaaa", "aaa", "aa"};
        // 参数类型省略 + 大括号/return省略
        Arrays.sort(arr,(o1,o2) -> o2.length()-o1.length());
        //输出结果:[aaaa, aaa, aa, a]
        System.out.println(Arrays.toString(arr));
    }
}

5.3 扩展知识:空指针风险与防御式编程

在实际开发中,如果数组中混入了 null 值,直接调用 .length() 会立即抛出 NullPointerException

Java 8 的 Comparator 提供了 nullsFirstnullsLast 工厂方法,能让我们优雅地定义空值的排序位置(排最前或排最后),从而避免程序崩溃。

示例:将 null 值视为最小值,排在最前面

java 复制代码
// 处理可能包含 null 的字符串数组
Arrays.sort(arr, Comparator.nullsFirst(Comparator.comparing(String::length)));
相关推荐
xiaoye-duck17 小时前
【C++:异常】C++ 异常讲解指南:从理论到实践,深入理解栈展开和优雅处理程序错误
开发语言·c++·异常
SarL EMEN18 小时前
海康威视摄像头ISUP(原EHOME协议) 摄像头实时预览springboot 版本java实现,并可以在浏览器vue前端播放(附带源码)
java·前端·spring boot
qq_4523962318 小时前
【工程实战】第八篇:报告美学 —— Allure 深度定制:让 Bug 定位精准到秒
开发语言·python·bug
考虑考虑18 小时前
图片居中
java·后端·java ee
Zqrnja18 小时前
PTA 2026天体选拔赛(多校联赛)L2-1 仪式网络(C++ 含代码解释)
开发语言·c++
llm大模型算法工程师weng18 小时前
负载均衡做什么?nginx是什么
运维·开发语言·nginx·负载均衡
有梦想的攻城狮18 小时前
java中的EnumSet使用详解
java·set·bitset·enumset
逆境不可逃18 小时前
【后端新手谈13】VO、BO、PO、DO、DTO:Java 分层开发的 5 大核心数据对象
java·开发语言
古月方枘Fry18 小时前
三层交换+VRRP实现负载
开发语言·网络·php
qq_54702617918 小时前
Java 中的 Caffeine 缓存详解
java·开发语言·缓存