体验Lambda的更优写法
假设我们计算两个数的和,还要求用到一个接口的抽象方法来实现,这时候我们会为了不再跟麻烦点而选择使用匿名内部类的方式,new一个这个接口的实现类。为此我们还要重写了里面的抽象方法。
//定义一个有抽象方法的接口
interface Myinter{
int getSum(int a,int b);
}
//使用匿名内部类的方式:
int sum=getSum(new Myinter() {
@Override
public int getSum(int a, int b) {
return a+b;
}
},120,180);
System.out.println(sum);
public static int getSum(Myinter mi,int a,int b){
return mi.getSum(a,b);
}
然后我们就可以在main方法中测试一下结果。那如果用Lambda 呢?
int newSum=getSum((a,b)->a+b,120,180);
System.out.println(newSum);
这样就可以打印出结果了。
完整代码:
/*
* 体验Lambda的更优写法
* */
//定义一个有抽象方法的接口
interface Myinter{
int getSum(int a,int b);
}
public class DemoOfLambda {
public static void main(String[] args) {
//使用匿名内部类的方式:
int sum=getSum(new Myinter() {
@Override
public int getSum(int a, int b) {
return a+b;
}
},120,180);
System.out.println(sum);
//体验Lambda的更优写法
int newSum=getSum((a,b)->a+b,120,180);
System.out.println(newSum);
}
public static int getSum(Myinter mi,int a,int b){
return mi.getSum(a,b);
}
}
结果:
300
300
Process finished with exit code 0
这个时候你可能会有一个疑问:一个求和的事情,为什么这么麻烦呢,完全可以a+b计算一下就可以了。但是在我们实际运用的时候我们可能会有很多一次性的操作,比如实现一个具有抽象方法的接口,以此来做一下事情。如果我们不知道这种表达的方法,我们一般会用到匿名内部类的方式,而Lambda将匿名内部类实现的操作更加简洁,优雅地实现了。
做什么,而不是怎么做
对于我们想要做的事System.out.println("多线程任务执行!"),要实现,用到匿名内部类的时候:
public class Demo04ThreadNameless {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程任务执行!");
}
}).start();
}
}
我们真的希望创建一个匿名内部类对象吗?不!。
我们真正希望做的事情是:将 run 方法体内的代码传递给Thread 类知晓。
传递一段代码才是我们真正的目的。
借助Java 8的全新语法,上述 Runnable 接口的匿名内部类写法可以通过更简单的Lambda表达式达到等效:
public class Demo02LambdaRunnable {
public static void main(String[] args) {
new Thread(() ‐> System.out.println("多线程任务执行!")).start(); // 启动线程
}
}
Lambda表达式的标准格式为:
(参数类型 参数名称) ‐> { 代码语句;return 值; }
-> 是新引入的语法格式,代表指向动作(做什么事)。
大括号内的语法与传统方法体要求基本一致
上面的那个求和的格式是Lambda表达式的省略格式。
在Lambda标准格式的基础上,使用省略写法的规则为:
1. 小括号内参数的类型可以省略;
2. 如果小括号内有且仅有一个参,则小括号可以省略;
3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
Lambda的使用前提
1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。
无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用 Lambda。
2. 使用Lambda必须具有上下文推断。
也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。