Java基础快速入门面向对象高级之Lambda表达式深度解析
在Java中,Lambda表达式是一种匿名函数或表达式,它可以用来表示一个方法。自从Java 8引入以来,Lambda表达式极大地增强了Java的编程能力,特别是在处理集合、并发编程和多线程等方面。Lambda表达式使得代码更加简洁、易读,并且提高了代码的表达能力。
项目代码结构
src/
└── com/
└── wb/
├── test1/
│ └── TestSwimming.java
├── test2/
│ └── TestLambda.java
├── test3/
│ └── StringHandlerDemo.java
├── test4/
│ └── RandomNumHandlerDemo.java
├── test5/
│ └── CalculatorDemo.java
├── test6/
│ └── Test6.java
└── test7/
└── Test.javaLambda表达式初体验与函数式编程思想
1 ) 从匿名内部类到Lambda
以前我们调用一个接口方法时,通常需要传入一个匿名内部类对象。例如,有一个游泳接口 Swimming,里面有一个 swim() 方法,我们这样调用:
goSwimming(new Swimming() {
@Override
public void swim() {
System.out.println("铁汁, 我们去游泳吧");
}
});
采用 Lambda表达式 后,可以简化为:
goSwimming(() -> System.out.println("铁汁, 我们去游泳吧"));
运行结果完全一致。这说明 Lambda表达式可以理解为对匿名内部类的简化(本质上两者有区别,后文会说明)。
2 ) 函数式编程思想
通过对比可以发现,匿名内部类的写法里,我们不仅要关注“做什么”(打印一句话),还要关注“怎么做”(创建匿名内部类对象、重写方法)。而Lambda表达式让我们把注意力完全集中在要做什么上面,至于怎么创建对象、怎么重写方法这些语法细节,都由编译器在背后处理了。
这种更关注做什么,而不是怎么做的编程思想,就是函数式编程思想(Functional Programming)。Lambda表达式正是这种思想在Java中的体现。
Lambda表达式的标准格式和使用前提
1 ) 标准格式
Lambda表达式由三部分组成:(形式参数) -> { 代码块 }
- 形式参数:如果有多个参数,用逗号分隔;如果没有参数,留空即可
- 箭头 ->:由英文横线和大于号组成,表示将参数传递给后面的代码块
- 代码块:具体要执行的内容,相当于方法体
2 ) 使用前提
Lambda表达式并不是任何地方都能用,必须满足两个条件:
- 操作的必须是一个接口。
- 接口中有且仅有一个抽象方法。
这种接口也被称为函数式接口。
3 ) 示例:无参数无返回值
接口定义(ShowHandler):
interface ShowHandler {
void show();
}
测试类:
public class TestLambda {
public static void main(String[] args) {
// 匿名内部类方式
useShowHandler(new ShowHandler() {
@Override
public void show() {
System.out.println("我是匿名内部类中的show方法");
}
});
// Lambda方式
useShowHandler(() -> System.out.println("我是Lambda中的show方法"));
}
public static void useShowHandler(ShowHandler showHandler) {
showHandler.show();
}
}分析:接口中只有一个 show() 方法,无参数,无返回值。
Lambda表达式 () -> System.out.println(...) 中,括号内无参数,箭头后直接写要执行的事情。
Lambda表达式练习:带参数无返回值
当接口方法带有参数时,Lambda表达式也需要在括号内声明参数。
接口定义(StringHandler):
interface StringHandler {
void printMessage(String msg);
}
使用示例:
public class StringHandlerDemo {
public static void main(String[] args) {
// 匿名内部类
useStringHandler(new StringHandler() {
@Override
public void printMessage(String msg) {
System.out.println("我是匿名内部类" + msg);
}
});
// Lambda
useStringHandler(msg -> System.out.println("我是Lambda表达式" + msg));
}
public static void useStringHandler(StringHandler stringHandler) {
stringHandler.printMessage("itheima");
}
}要点:方法 printMessage 有一个参数,所以Lambda的括号内需要写上参数名(参数类型可以省略,后面会讲)。如果只有一个参数,括号也可以省略,如 msg -> ...。
Lambda表达式练习:无参数有返回值
如果接口方法有返回值,Lambda表达式必须使用 return 语句返回结果。
接口定义(RandomNumHandler):
interface RandomNumHandler {
int getNumber();
}
使用示例:
import java.util.Random;
public class RandomNumHandlerDemo {
public static void main(String[] args) {
// 匿名内部类
useRandomNumHandler(new RandomNumHandler() {
@Override
public int getNumber() {
Random r = new Random();
int num = r.nextInt(10) + 1;
return num;
}
});
// Lambda
useRandomNumHandler(() -> {
Random r = new Random();
int num = r.nextInt(10) + 1;
return num;
// 注意: 如果lambda所操作的接口中的方法有返回值, 一定要通过return语句将结果返回
// 否则会出现编译错误
});
}
public static void useRandomNumHandler(RandomNumHandler randomNumHandler) {
int result = randomNumHandler.getNumber();
System.out.println(result);
}
}注意:无参数但需要返回值时,括号不能省略;方法体中的代码块如果有多条语句,大括号也不能省略。
Lambda表达式练习:带参数带返回值
这是最完整的形态:既有参数,又有返回值。
接口定义(Calculator):
interface Calculator {
int calc(int a, int b);
}
使用示例:
public class CalculatorDemo {
public static void main(String[] args) {
// 匿名内部类
useCalculator(new Calculator() {
@Override
public int calc(int a, int b) {
return a + b;
}
});
// Lambda
useCalculator((a, b) -> a + b);
}
public static void useCalculator(Calculator calculator) {
int result = calculator.calc(10, 20);
System.out.println(result);
}
}说明:参数 a 和 b 的类型可以省略,方法体只有一条返回语句时,可以省略大括号和 return,直接写表达式。
Lambda表达式的省略模式
Lambda表达式提供了一些简化写法,让代码更简洁。
1 ) 省略规则
- 参数类型可以省略,但如果有多个参数,不能只省略一个(要么都省略,要么都保留)。
- 如果参数只有一个,小括号可以省略。
- 如果代码块只有一条语句,可以省略大括号、分号和 return(这三个必须一起省略)。
2 ) 示例:针对省略规则的综合练习
原始接口:
interface Inter {
double method(double a, double b);
}
完整Lambda:
useInter((double a, double b) -> {
return a + b;
});
应用省略规则后:
useInter((a, b) -> a + b);
完整调用代码:
public class Test6 {
public static void main(String[] args) {
useInter((a, b) -> a + b);
}
public static void useInter(Inter i) {
double result = i.method(12.3, 22.3);
System.out.println(result);
}
}3 ) 对其他练习的省略优化
test2(无参无返回值):
useShowHandler(() -> System.out.println("我是Lambda中的show方法"));
因为无参,括号不能省;只有一条语句,可以省略大括号和分号。
test3(一个参数无返回值):
useStringHandler(msg -> System.out.println("我是Lambda表达式" + msg));
参数类型省略,且只有一个参数,小括号省略;一条语句,省略大括号和分号。
test4(对应上述无参有返回值,方法体多条语句):
无法省略大括号,因为方法体有两条语句,必须保留 {} 和 return。
test5(有参有返回值,方法体一条语句):
useCalculator((a, b) -> a + b);
省略了参数类型、大括号和 return。
匿名内部类与Lambda表达式的区别
| 区别点 | 匿名内部类 | Lambda表达式 |
|---|---|---|
| 所属类型 | 可以是接口、抽象类,甚至具体类 | 只能操作接口 |
| 使用限制 | 接口中抽象方法数量不限 | 接口中必须有且仅有一个抽象方法 |
| 实现原理 | 编译后生成独立的 .class 文件(如 Test$1.class) | 编译时不生成单独的 .class 文件,运行时动态生成字节码 |
1 ) 验证编译结果
接口:
interface Inter {
void show();
}
测试类:
public class Test {
public static void main(String[] args) {
// 匿名内部类
useInter(new Inter() {
@Override
public void show() {
System.out.println("匿名内部类的show方法");
}
});
}
public static void useInter(Inter i) {
i.show();
}
}编译后,在 out 目录下可以看到:
Inter.class(接口字节码)Test.class(测试类字节码)Test$1.class(匿名内部类生成的字节码)
如果使用Lambda表达式,编译后不会生成 $1.class,对应的字节码会在运行时动态生成,不保留在硬盘上。
结语
Lambda表达式是 Java 8 引入的重要特性,它让代码更简洁,同时将编程思维从“怎么做”引导到“做什么”。
掌握Lambda的格式、使用前提、省略规则以及与匿名内部类的区别,是Java进阶的必经之路。希望本文能帮助你快速入门Lambda表达式。
到此这篇关于Java基础快速入门面向对象高级之Lambda表达式深度解析的文章就介绍到这了,更多相关Java Lambda表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringCloud Config分布式配置中心使用教程介绍
springcloud config是一个解决分布式系统的配置管理方案。它包含了 client和server两个部分,server端提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client端通过接口获取数据、并依据此数据初始化自己的应用2022-12-12
SpringBoot在 POM 中引入本地 JAR 包的方法
在开发 Spring Boot 应用程序时,您可能需要使用本地 JAR 包来添加自定义库或功能,本文将介绍在 Spring Boot 项目的 POM 文件中如何引入本地 JAR 包,感兴趣的朋友跟随小编一起看看吧2023-08-08
Spring Boot使用Redisson实现滑动窗口限流的项目实践
滑动窗口限流是一种流量控制策略,用于控制在一定时间内的请求频率,本文主要介绍了Spring Boot使用Redisson实现滑动窗口限流的项目实践,具有一定的参考价值,感兴趣的可以了解一下2024-03-03
SpringBoot之spring.factories的使用方式
这篇文章主要介绍了SpringBoot之spring.factories的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-01-01
Spring AI 结构化输出 + 大模型参数全解析(含千问调优)
在构建一个基于Spring AI的结构化输出系统,并结合大模型参数优化(如千问调优),我们可以采用一系列的步骤和策略,这篇文章主要介绍了Spring AI 结构化输出 + 大模型参数全解析(含千问调优),需要的朋友可以参考下2026-06-06


最新评论