目录
大家好,我是jstart千语。今天总结一下lambda表达式。lambda表达式在后面的streamAPI和mybatis-plus都用得非常多。是很有必要学习的。
说白了,lambda表达式就是简化函数式接口的匿名内部类的书写。
什么是函数式接口?就是只有一个抽象方法的接口。
什么是匿名内部类?就是在实参中书写内部类,传递给方法的形参。
lambda表达式是函数式编程的产物,与我们面向对象编程不同。所以他们的实现方式也会不同。我会从面向对象的方式讲起。
Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码,它可以写出更简洁、更灵活的代码,作为为一种更紧凑的代码风格,使 Java 语言表达能力得到了提升。
一、面向对象的处理方法
对于使用不同的工具来发送消息的功能,如果是使用面向对象的思想,需要先定义一个接口,然后让不同的工具来实现这个接口,并重写它的抽象方法,例如:
接口:
public interface sendMessage {
void send();
}
Email实现类:
public class Email implements sendMessage {
@Override
public void send() {
System.out.println("use email send message");
}
}
phone实现类:
public class phone implements sendMessage {
@Override
public void send() {
System.out.println("use phone send message");
}
}
具体运行的代码:
public class Main {
public static void main(String[] args) {
sendMessage email = new Email();//创建email的实例
email.send(); //调用实现类的方法
}
}
输出:
总结:
显然,如果使用面向对象的思想,要先自己写实现类,然后重写方法,然后创建对象,最好再调用方法。相对来说比较麻烦,特别是某种情况只用一次的时候。
二、函数式编程的处理方法
这是一种简化代码的一种书写风格,可以直接将接口的具体实现写在lambda表达式里,不需要再进行实例化接口、创建对象、调用方法。
比如基于上述的例子,我再补充一个使用WX来发送消息的实现:
先使用匿名内部类:
public static void main(String[] args) {
message(new SendMessage() {
@Override
public void send() {
System.out.println("use wx send message");
}
});
}
public static void message(SendMessage sendMessage) {
sendMessage.send();
}
lambda改造:
public static void main(String[] args) {
message(() -> {
System.out.println("use wx send message");
});
}
public static void message(SendMessage sendMessage) {
sendMessage.send();
}
lambda改造规则
改造规则遵循:可推导可省略的思想。也就是说如果可以由java推导出来的就可以省略。
具体如下:
- 从接口名到方法名都可以省略,也就是从new...到方法名都可以省略,参数和方法体之间用 -> 连接。
- 参数类型可以省略不写
- 如果只有一个参数,()可以省略;如果参数不止一个,那么()就不能省略,只能省略参数类型
- 如果方法体只有一行,{}可以省略、return可以省略,方法体内的 ;可以省略
示例:
public static void main(String[] args) {
String result = message("李雷","hello",new SendMessage(){
@Override
public String send(String user, String message) {
System.out.println("send " + message + " to " + user);
return "success";
}
});
System.out.println("result: " + result);
}
public static String message(String user,String message,SendMessage sendMessage) {
return sendMessage.send(user, message);
}
lambda表达式:
public static void main(String[] args) {
String result = message("李雷","hello",(user, message) -> {
System.out.println("send " + message + " to " + user);
return "success";
});
System.out.println("result: " + result);
}
public static String message(String user,String message,SendMessage sendMessage) {
return sendMessage.send(user, message);
}
输出:
三、补充:函数式接口
函数式接口就是指只有一个抽象方法的接口,可以使用@FunctionalInterface来标记。
- 不加这个注解,只要接口里面只有一个方法,那这个接口也是函数式接口
- 加了这个注解,如果接口里面不止一个抽象方法,会报编译错误。
- 实际使用中,还是添加这个注解,因为这样可以做到显式地声明,更清楚地知道这个接口的使用意图。