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
标签:变量,int,局部变量,参数,Lambda,string 来源: https://www.cnblogs.com/Nilekai/p/16470545.html