Lambda表达式详解
一、什么是Lambda表达式?
1.函数式编程的引入
Java是一门面向对象的语言,优点有很多,比如增加了程序的灵活性和可维护性,易拓展,可设计出高内聚、低耦合的系统结构。但相应的缺点也很明显,比如为了写可重用的代码而写了很多无用的代码,造成冗余。
这时,可以试着引入函数编程的思想。函数式变成的表达方式更加符合人类日常生活中的语法,即“怎么做”而不是“谁来做”,代码可读性更强,清晰简洁。
2.Lambda表达式
Lambda表达式(“λ”,读音为 ˈlamdə ,“b”不发音)是JDK8中新引入的特性,可代替匿名内部类,使代码更加简洁可读。
二、如何使用Lambda表达式
1.Lambda表达式的标准格式
<1>格式
(参数类型 参数名) -> {
方法体;
return 返回值;
}
<2>注意:
- 小括号中的参数可以有多个,多个之间使用逗号隔开即可。
2. -> 箭头是一个运算符,表示指向性动作。
- 大括号中的内容和传统方法基本一致
2.匿名内部类使用和Lambda表达式的引入
<1>匿名内部类:就是内部类的简化写法
<2>前提:存在一个类或接口,这里的类可以是具体类也可以是抽象类
<3>格式:
new 类名或接口名(){
重写方法;
}
<4>本质:是一个继承了该类或实现了该接口的子类匿名对象,虽然new的是接口或类,但实际new的是实现类或子类
<5>Lambda表达式的引入
①用创建对象的方式,不用匿名内部类,开启多线程打印“多线程启动了”
public class Test02 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
new Thread(mr).start();
}
}
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("多线程启动了");
}
}
②用匿名内部类作为参数,开启多线程打印“多线程启动了”
修改前:
public class Test02 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
new Thread(mr).start();
}
}
修改后:
public class Test02 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程启动了");
}
}).start();
}
}
由以上代码可看出,实际有用的代码只有“System.out.println(“多线程启动了”);”,但为了让这行代码生效,却写了其他无用的代码,造成了冗余,那么我们看一下用Lambda表达式会如何。
③用Lambda表达式
修改前:
public class Test02 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程启动了");
}
}).start();
}
}
修改后:
public class Test02 {
public static void main(String[] args) {
new Thread(()-> System.out.println("多线程启动了")).start();
}
}
由以上可看出,()-> System.out.println(“多线程启动了”)是重写了Runnable接口中的run()方法,因为run()方法没有参数,所以用“( )”表示。
如果重写的方法有参数该如何?
<6>重写的方法中有参数,Lambda表达式该如何使用?
定义一个接口Calculator,里面有一个抽象方法method,参数是整数类型的a和b,返回值类型是int
public interface Calculator {
public abstract int method(int a,int b);
}
定义一个invokeMethod方法,参数类型是Calculator和int类型的a与b,返回值类型void,调用method方法
public static void invokeMethod(int a, int b, Calculator c) {
int result = c.method(a, b);
System.out.println(result);
}
计算110减70的结果
public static void main(String[] args) {
invokeMethod(100, 70, (a, b) -> a - b);
//控制台打印:result:30
}
接口中的抽象方法方法是“int method(int a,int b)”,Lambda表达式重写了抽象方法,将“a-b”return给了result
3.Lambda表达式的省略规则
①小括号中的参数类型可以省略。
②如果小括号中只有一个参数,那么可以省略小括号。
③如果大括号里面只有一条语句,那么可以省略大括号,return,以及分号。
4.Lambda表达式的使用前提
①必须有接口(不能是抽象类),接口中必须有且仅有一个需要被重写的抽象方法
②必须支持上下文推导,也就是方法的参数类型或局部变量的类型必须是Lambda对应的接口类型
另:
Lambda表达式是匿名内部类的简化写法, 但是它不能完全替换匿名内部类
1.匿名内部类不仅支持接口,还支持类。 但是Lambda仅仅支持接口。
2.匿名内部类可以重写多个方法。 但是Lambda表达式仅仅可以重写一个