函数式编程 作为一种编程方式,早在1958 年就出现了,在编程界的大佬手上用的可是风生水起,但是我们在日常学习中却很少使用,那是因为我们所用的编程方式是 命令式编程 方式,创建变量、赋值、循环等等这种按部就班的程序操作就是命令式编程方式,而函数式编程相比于命令式编程则更倾向于数学思想,举个栗子,我们把命令式编程比作数学不好的人,而函数式编程比较数学好的人,当计算一道 1 到 10 的和的时候,数学差的人会想到将 1 到 10 的值逐个加起来计算,而数学好的人则会用求和公式来计算,虽然两种方式都能得到答案,但是数学好的人的方法更加简洁,更令改卷老师喜欢。函数式编程就是这样,代码更加简洁,开发速度快。
函数式编程的基础就是 λ 演算(Lamdba 演算),基于 λ 演算,在 Java8 之后引入了 Lambda 表达式,也称 闭包,Lambda 表达式可以将一个函数以参数的方式添加到方法中。
比如,我们给一个按钮添加监听器:
Button button = new Button("按钮");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("诶嘿哈哈哈哈哈,按钮来咯");
}
});
以上方式需要通过匿名类的方式来实现,而用 Lambda 表达式就是这样的:
Button button = new Button("按钮");
button.addActionListener(actionEvent -> System.out.println("诶嘿哈哈哈哈哈,按钮来咯"));
六行的代码用一行解决,代码量更加简洁,可读性更强,且使用起来也很方便。
Lambda 表达式 的语法格式为以下五种情况:
//没有参数, 直接返回1
() -> 1
//一个参数, 返回 x + 1
x -> x + 1
//有参数, 返回 x + y
(x, y) -> x + y
//参数指定类型, 返回 x + y
(int x, int y) -> x + y
//有{}, {}里执行代码块
(int x, int y) -> {
System.out.println("诶嘿哈哈哈哈哈,x 来咯:" + x);
System.out.println("诶嘿哈哈哈哈哈,y 来咯:" + y);
}
测试这五种类型:
public class Demo {
public static void main(String[] args) {
//没有参数, 直接返回1
Test01 test01 = () -> 1;
//一个参数, 返回 x + 1
Test02 test02 = x -> x + 1;
//有参数, 返回 x + y
Test03 test03 = (x, y) -> x + y;
//参数指定类型, 返回 x + y
Test03 test04 = (int x, int y) -> x + y;
//有{}, {}里执行代码块
Test04 test05 = (int x, int y) -> {
System.out.println("诶嘿哈哈哈哈哈,x 来咯:" + x);
System.out.println("诶嘿哈哈哈哈哈,y 来咯:" + y);
};
//执行
System.out.println("test01 返回1: " + test01.test());
System.out.println("test02 返回114513+1: " + test02.test(114513));
System.out.println("test03 返回114+514: " + test03.test(114, 514));
System.out.println("test04 返回1919+810: " + test04.test(1919,810));
System.out.println("test05 不返回, 参数为1919, 810: ");
test05.test(1919,810);
}
}
//定义各个接口
interface Test01{
//无参方法
int test();
}
interface Test02{
//一个参数
int test(int x);
}
interface Test03{
//两个参数
int test(int x, int y);
}
interface Test04{
//两个参数,不返回值
void test(int x, int y);
}
执行结果:
需要注意的是:Lambda表达式中变量都是 不可变 的,因此如果想访问外层的变量,最好将变量类型声明为 final,不用声明 final 也可以,但是必须保证变量在后面不能被修改。
正常代码:
public class Demo {
public static void main(String[] args) {
//定义一个参数
final int x = 1;
//没有参数, 直接返回1
Test01 test01 = () -> x;
//执行
System.out.println("test01 返回1: " + test01.test());
}
}
interface Test01{
//无参方法
int test();
}
执行结果:
Lambda 表达式引用方法:对于表达式中的一些方法,当参数列表和返回值相同时,且没有参加其他逻辑时,我们可以用 :: 符号来进一步简化 Lambda 表达式。
普通 Lambda 表达式:
public class Demo {
public static void main(String[] args) {
//返回该参数和, x + y = Integer.sum(x, y)
Test01 test01 = (x, y) -> Integer.sum(x, y);
//执行
System.out.println("test01 返回1+2: " + test01.test(1,2));
}
}
interface Test01{
int test(int x, int y);
}
简化后的 Lambda 表达式:
public class Demo {
public static void main(String[] args) {
//返回该参数和, x + y = Integer.sum(x, y)
Test01 test01 = Integer::sum;
//执行
System.out.println("test01 返回1+2: " + test01.test(1,2));
}
}
interface Test01{
int test(int x, int y);
}
执行结果: