文章目录
- 回顾下Interface
- Why Interface
- Interface例子
- 需求
- 实现需求
- Lambda表达式
- Why Lambda
- Lambda表达式
- Lambda表达式实现`send()`
- 无参数的抽象方法
- 有参数的抽象方法
- 多参数、有返回值的抽象方法
- 赋值给变量
- Email or SMS?
- Lambda表达式的限制
- Reference
Lambda表达式是Java函数式编程的核心概念之一,是一种语法糖
- 语法糖(Syntactic sugar):计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用
- Java中其他的语法糖:for-each,断言等等
用于简化实现函数式接口Functional Interface
回顾下Interface
Why Interface
接口用来定义一个协议或约定,只提供抽象方法
- 抽象方法 Abstract Method:只声明方法,不提供方法的具体实现
- 但JDK1.8以后,接口可以有方法体与具体实现的方法(default)
将接口的声明与具体实现分开,业务中只需要关心方法,不需要关心具体的实现类
从而实现代码的解耦和模块化
Interface例子
需求
通过一个方法发送多种不同形式的消息,比如Email邮件消息、SMS短消息
实现需求
-
定义
Message
接口public interface Message{void send(); // abstract method }
-
Email
实现Message
接口public class Email implements Message{String email;public Email() {}@Overridepublic void send() {System.out.println("This is an email.");} }
-
Sms
实现Message
接口public class Sms implements Message{String phoneNumber;public Sms() {}@Overridepublic void send() {System.out.println("This is a sms.");} }
-
main中测试
public class Main {public static void main(String[] args) {Message email = new Email();Message sms = new Sms();sendMessage(email);sendMessage(sms);}static void sendMessage(Message message){// 参数类型为Message接口,可以传入Email或SMS对象message.send();} }
Lambda表达式
Why Lambda
可以看出,上面的例子中仅发送一条消息,也需要很多步骤:
- 先根据Message接口实现Email或Sms类
- 在实现类中实现接口的抽象方法
- 创建Message的Email或Sms实例
- 发送
Lambda表达式可以提供一种快速简介的方式实现接口,抽象方法的实现直接在Lambda表达式里定义
Lambda表达式
(parameters)->{statements;}
()
括号 Parentheses:对应抽象方法的括号,里面是抽象方法的参数- 如果只有一参数,可以省略:
parameter ->{statements;}
- 如果只有一参数,可以省略:
-
连字号 Hyphen>
箭头Arrow{}
大括号Curly Braces:Lambda体,对应抽象方法的大括号,里面放具体行为- 如果只有一行,可以省略:
(parameters) -> expression
- 如果只有一行,可以省略:
Lambda表达式实现send()
无参数的抽象方法
public interface Message{void send(); // abstract method
}
- 一行:
(parameters) -> expression
sendMessage(() -> System.out.println("This is an email.");
);
输出:
This is an email.
- 多行:
(parameters)->{statements;}
sendMessage(() -> {System.out.println("This is an email.");System.out.println("Hi there!");
});
输出:
This is an email.
Hi there!
有参数的抽象方法
public interface Message{void send(String name); // abstract method
}
public class Main {public static void main(String[] args) {sendMessage((name) -> {System.out.println("This is an email to " + name);});}static void sendMessage(Message message){// 参数类型为Message接口,可以传入Email或SMS对象message.send("Hansdas");}
}
由于只有一个参数跟一行代码,Lambda表达式可以简化
public class Main {public static void main(String[] args) {sendMessage(name -> System.out.println("This is an email to " + name););}static void sendMessage(Message message){// 参数类型为Message接口,可以传入Email或SMS对象message.send("Hansdas");}
}
多参数、有返回值的抽象方法
public interface Message{string send(String name, String title); // abstract method
}
public class Main {public static void main(String[] args) {sendMessage((name, title) -> {System.out.println("This is an email to " + title+ " " +name);return "success!";});}static void sendMessage(Message message){// 参数类型为Message接口,可以传入Email或SMS对象String status = message.send("Hansdas", "Mr");}
}
赋值给变量
Lambda表达式也可以赋值给对应接口类型的变量
public class Main {public static void main(String[] args) {Message lambda = (name, title) -> {System.out.println("This is an email to " + title+ " " +name);return "success!";};}static void sendMessage(Message message){// 参数类型为Message接口,可以传入Email或SMS对象String status = message.send("Hansdas", "Mr");}
}
Email or SMS?
回到开始的需求,需要发送Email或SMS类型的信息,此时不需要创建对应类实现接口、实例化对象、调用对应方法
只需要早Lambda表达式中稍作修改
public class Main {public static void main(String[] args) {sendMessage((name, title) -> {System.out.println("This is an SMS to " + title+ " " +name);return "success!";});}static void sendMessage(Message message){// 参数类型为Message接口,可以传入Email或SMS对象String status = message.send("Hansdas", "Mr");}
}
Lambda表达式的限制
- Lambda表达式只能用于函数式接口
- 函数式接口Functional Interface:有且只有一个抽象方法的接口
- 因为接口如果有多个抽象方法,lambda不值得要实现哪个抽象方法
- 可以使用
FunctionalInterface
标注函数式接口,建议使用,- 但不是必须的,只要满足函数式接口【只有一个抽象方法】的条件,Java会自动将其作为函数式接口
Reference
依然来自AlbertShen