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; } }