Lambda 表达式、方法引用(Method Reference)语法

Lambda 表达式

使用Lambda必须先定义一个只有一个抽象类的接口(或者用java、spring boot等内置的接口)

复制代码
// 1. 定义接口
interface MyCommand {
    // 里面只能有一个没写具体代码的方法
    void doWork(); 
}
 // --- 传统写法(比较啰嗦) ---
        MyCommand cmd1 = new MyCommand() {
            @Override
            public void doWork() {
                System.out.println("这是我的自定义任务!");
            }
        };
        cmd1.doWork(); // 调用

        // --- Lambda 写法(超级简单) ---
        MyCommand cmd2 = () -> System.out.println("这是我的自定义任务!");
        cmd2.doWork(); // 调用

1、无参数,无返回值

复制代码
// 传统写法
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("执行任务");
    }
};

// Lambda 写法
Runnable r2 = () -> System.out.println("执行任务");

2、有参数,无返回值

复制代码
// 传统写法
Consumer<String> c1 = new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
};

// Lambda 写法
Consumer<String> c2 = (s) -> System.out.println(s);

3、单参数可省略括号

复制代码
Consumer<String> c2 = s -> System.out.println(s);

4、有参数、有返回值

复制代码
// 传统写法:要写 5 行代码
MathOperation add = new MathOperation() {
    @Override
    public int operate(int a, int b) {
        return a + b;
    }
};

// Lambda 写法:只要 1 行代码
MathOperation add = (a, b) -> a + b;

Method Reference

表格

Lambda 写法 方法引用简化版 类型说明
(admin) -> admin.getName() admin::getName 对象实例方法引用(引用类的实例方法)
(str) -> System.out.println(str) System.out::println 对象实例方法引用(引用现有对象的实例方法)
(a, b) -> Math.max(a, b) Math::max 静态方法引用(引用类的静态方法)
复制代码
import java.util.function.Function; // Java 自带的"接收者"接口

import java.util.function.Function;

public class Test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("张三");

        // =========================================================
        // 写法 1:传统匿名内部类 (最啰嗦,像写八股文)
        // =========================================================
        Function<User, String> func1 = new Function<User, String>() {
            @Override
            public String apply(User u) {
                return u.getName();
            }
        };
        System.out.println("写法 1 结果:" + func1.apply(user));


        // =========================================================
        // 写法 2:Lambda 表达式 (简化版,去掉了多余的外壳)
        // =========================================================
        // (u) -> u.getName(); 意思是:给我一个 u,返回 u.getName()
        Function<User, String> func2 = (u) -> u.getName();
        System.out.println("写法 2 结果:" + func2.apply(user));


        // =========================================================
        // 写法 3:方法引用 (极致简化,你项目中用的就是这个)
        // =========================================================
        // User::getName 意思是:直接用 User 的 getName 方法
        Function<User, String> func3 = User::getName;
        System.out.println("写法 3 结果:" + func3.apply(user));
    }
}

class User {
    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

// 1. 自定义一个接口,规定方法名叫 extract
interface MyDataExtractor {
    String extract(User u); // 注意:这里我故意不叫 apply,叫 extract
}

public class Test {
    public static void main(String[] args) {
        User user = new User();
        user.setName("张三");

        // =========================================================
        // 写法 1:传统写法 (老老实实实现 extract 方法)
        // =========================================================
        MyDataExtractor func1 = new MyDataExtractor() {
            @Override
            public String extract(User u) { // 必须叫 extract
                return u.getName();
            }
        };
        System.out.println("写法 1 结果:" + func1.extract(user));


        // =========================================================
        // 写法 2:Lambda 写法 (自动填入 extract 的坑里)
        // =========================================================
        // 虽然你没写 extract,但 Java 知道这个接口只有一个坑叫 extract
        MyDataExtractor func2 = (u) -> u.getName(); 
        System.out.println("写法 2 结果:" + func2.extract(user)); // 调用时还是用 extract


        // =========================================================
        // 写法 3:方法引用 (自动填入 extract 的坑里)
        // =========================================================
        MyDataExtractor func3 = User::getName;
        System.out.println("写法 3 结果:" + func3.extract(user)); // 调用时还是用 extract
    }
}

class User {
    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}
相关推荐
乘风gg2 小时前
为什么AI 时代来临,大部分人吃不到红利
前端·ai编程·claude
恋猫de小郭2 小时前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
IT_陈寒2 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
恋猫de小郭2 小时前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter
小bo波3 小时前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
Hyyy3 小时前
理解LLM的基本工作原理:预训练、微调、推理的区别
前端
Gatlin4 小时前
前端逆向与反逆向:一场猫鼠游戏的底层逻辑与实战
前端
Pedantic4 小时前
本地通知(Local Notifications)学习笔记
前端
森蓝情丶5 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
爱勇宝5 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员