Lambda
特点
- 匿名:它不像普通的方法那样有一个明确的名称
- 函数:为Lambda函数不像方法那样属于某个特定的类。但和方法一样,Lambda有参数列表、函数主体、返回类型,还可能有可以抛出的异常列表。
- 传递:Lambda表达式可以作为参数传递给方法或存储在变量中。
- 简洁:无需像匿名类那样写很多模板代码。
组成
- 参数列表
- 箭头
- Lambda主体
语法格式
(parameters) -> expression
(parameters) -> { statements; }(注意语句的花括号,和分号)
例如
//无参数,返回string
() -> "string"
//无参数,显示返回string
() -> {return "string";}
//int 参数,返回int
(int a, int b) -> a + b
//int 参数,使用方法引用
(int a, int b) -> Integer::sum
//简写声明类型由编译器推导,使用方法引用
(a, b) -> Integer::sum
局部变量
Lambda表达式也允许使用自由变量(不是参数,而是在外层作用域中定义的变量),就像匿名类一样。Lambda可以没有限制地捕获(也就是在其主体中引用)实例变量和静态变量。但局部变量必须显式声明为final,或事实上是final。换句话说,Lambda表达式只能捕获指派给它们的局部变量一次。
//可以捕获局部变量,但是之后没办法再修改此局部变量
public static void main(String[] args) {
int portNumber = 190;
Runnable r = () -> System.out.println(portNumber);
}
原因
实例变量和局部变量背后的实现有一个关键不同。实例变量都存储在堆中,而局部变量则保存在栈上。如果Lambda可以直接访问局部变量,而且Lambda是在一个线程中使用的,则使用Lambda的线程,可能会在分配该变量的线程将这个变量收回之后,去访问该变量。因此,Java在访问自由局部变量时,实际上是在访问它的副本,而不是访问原始变量。如果局部变量仅仅赋值一次那就没有什么区别了——因此就有了这个限制。
复合操作
可以把多个简单的Lambda复合成复杂的表达式。比如,你可以让两个谓词之间做一个or操作,组合成一个更大的谓词。
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g);
int result = h.apply(1);//4
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南