Lambda表达式
Lambda表达式主要形式
()->{}
()写形参,参数类型可省略。
{}里写单条语句或代码块。
中间->分割两部分,不可省略。
以线程为例
//一般写法
new Thread(new Runnable() {
@Override
public void run() {
/*线程执行任务*/
}
});
//lambda写法
new Thread(()->{/*线程执行任务*/});
省略规则(一般规则)
()里有多个参数时,用“,”隔开。如果只有一个参数时,()可以省略。如果没有参数()必须保留。
{}如果只有一条语句时,{}可以省略。如果恰好该条语句是return语句时,return必须省略。
例子
假如有这么几个接口
//加法
interface Add{
int doAdd(int a,int b);
}
//求相反数
interface Opposite{
int getOpposite(int b);
}
//输出 hello
interface Say{
void sayHello();
}
lambda 多参简写过程
//1.一般匿名实现类写法
Add add = new Add() {
@Override
public int doAdd(int a, int b) {
int sum = a + b;
return sum;
}
};
System.out.println(add.doAdd(6,1));
//2.lambda简单改写
Add add = (int a, int b) ->{
int sum = a + b;
return sum;
};
System.out.println(add.doAdd(6,1));
//3.参数类型可以省略
Add add = (a,b) ->{
int sum = a + b;
return sum;
};
System.out.println(add.doAdd(6,1));
//4.当{}里的语句可以化简成一句或者只有一句时{}可以省略(注意:如果是return语句,省略{}时关键字“return”也必须省略)
Add add = (a,b) -> a + b;
System.out.println(add.doAdd(6,1));
//--最后我们会发现输出是一样的,都是7
lambda 单参写法
//1.一般匿名实现类写法
Opposite operate = new Opposite() {
@Override
public int getOpposite(int b) {
return -b;
}
};
System.out.println(operate.getOpposite(10));
//2.lambda简单改写
Opposite operate = (int b) ->{
return -b;
};
System.out.println(operate.getOpposite(10));
//3.省略参数类型
Opposite operate = (b) ->{
return -b;
};
System.out.println(operate.getOpposite(10));
//4.省略()
Opposite operate = b ->{
return -b;
};
System.out.println(operate.getOpposite(10));
//5.省略{}
Opposite operate = b -> -b;
System.out.println(operate.getOpposite(10));
//--最后我们会发现输出是一样的,都是-10
lambda 无参写法
//1.一般匿名实现类写法
Say say = new Say() {
@Override
public void sayHello() {
System.out.println("hello");
}
};
say.sayHello();
//2.lambda简单改写
Say say = () ->{System.out.println("hello");};
say.sayHello();
//3.省略{}
Say say = () -> System.out.println("hello");
say.sayHello();
//--最后我们会发现都会输出 hello
优点
肉眼可见,用lambda表达式简写,可以省略很多代码,看上去简洁
为什么
是不是很神奇,不用写方法名就知道重写的是哪个方法,一下简化了那么多代码。
lambda表达式是jdk8新增的
对于参数是可以推导出来的,参考文档有这么一句话
The formal parameters of a lambda expression may have either declared types
or inferred types.
为什么可以推导,我们发现,上面给出的接口只有一个抽象方法,我们称之为函数式接口。
正是因为只有一个抽象方法,所以我们并不用关心方法名叫什么,只要关注参数和方法体就行。同样,我们在形式上也不用关注参数类型,因为只有一个抽象方法,可以推导出参数类型。这并不意味着我们不需要知道参数类型,因为我们在方法体中还要用到参数,所以还是要知道参数类型,只是可以在形式上不用写出来而已。
参考文献:
[1] James Gosling,Bill Joy,Guy Steele,Gilad Bracha,Alex Buckley.The Java® Language
Specification Java SE 8 Edition[OL]:601-611.https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf
PS: 如果有什么不对或疑惑的欢迎指出或讨论。如果觉得有帮助,就点个赞支持一下吧。