1.概述
Lambda表达式是JDK8开始后的一种新语法形式,其作用为简化匿名内部类的代码写法。
1.1 Lambda表达式的语法
Lambda表达式由三部分组成:
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
1.paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。
2.->:可理解为“被用于”的意思。
3.方法体:可以是表达式也可以是代码块,是函数式接口里方法的实现。
以下为一些示例:
//1.不需要参数,返回值为2 ()->2 //2.接收一个参数(数字类型),返回其二倍的值 x->2*x //3.接收2个参数(数字),并返回他们的和 (x,y)->x+y //4.接收2个int型整数,返回他们的乘积 (int x,int y)->x*y //5.接收一个string对象,并在控制台下打印,不返回任何值(看起来像是返回void) (String s)->System.out.print(s)
1.2 函数式接口
在了解lambda表达式之前,需要先理解什么是函数式接口,函数式接口定义:一个接口有且仅有一个抽象方法
(注意:函数式接口还需要声明@FunctionalInterface注解,这样编译器将会自动进行检测该函数式接口是否只有一个抽象方法)
如下实例:
@FunctionalInterface interface NoParameterNoReturn { //注意:只能有一个方法 void test(); }
2.Lambda表达式的基本使用
我们首先来准备几个接口:
//无返回值无参数 @FunctionalInterface interface NoParameterNoReturn { void test(); } //无返回值一个参数 @FunctionalInterface interface OneParameterNoReturn { void test(int a); } //无返回值多个参数 @FunctionalInterface interface MoreParameterNoReturn { void test(int a,int b); } //有返回值无参数 @FunctionalInterface interface NoParameterReturn { int test(); } //有返回值一个参数 @FunctionalInterface interface OneParameterReturn { int test(int a); } //有返回值多参数 @FunctionalInterface interface MoreParameterReturn { int test(int a,int b); }
Lambda表达式的作用是为简化匿名内部类的代码写法,实际上是创建了一个类,实现了接口,重写了接口的抽象方法(接口不能实例化,所以相当于实例化了一个匿名内部类)。
在没有使用Lambda表达式的时候的调用方式:
NoParameterNoReturn noParameterNoReturn=new NoParameterNoReturn() { @Override public void test() { System.out.println("hello"); } }; noParameterNoReturn.test();
使用Lambda表达式后:
public class lambda { public static void main(String[] args) { NoParameterNoReturn noParameterNoReturn=()->System.out.println("无参数返回值"); noParameterNoReturn.test(); OneParameterNoReturn oneParameterNoReturn=(int a)->System.out.println("一个参数无返回值:"+a); oneParameterNoReturn.test(10); MoreParameterNoReturn moreParameterNoReturn=(int a,int b)->System.out.println("多个参数无返回值:"+a+" "+b); moreParameterNoReturn.test(20,30); NoParameterReturn noParameterReturn=()->{ System.out.println("有返回值无参数"); return 0; }; int ret=noParameterReturn.test(); System.out.println(ret); OneParameterReturn oneParameterReturn=(int a)->{ System.out.println("有返回值有一个参数"); return a; }; ret=oneParameterReturn.test(50); System.out.println(ret); MoreParameterReturn moreParameterReturn=(int a,int b)->{ System.out.println("有返回值有多个参数"); return a+b; }; ret= moreParameterReturn.test(30,40); System.out.println(ret); } }
语法精简规则:
参数类型可以省略,如果需要省略,每个参数的类型都要省略。
参数的小括号里面只有一个参数,那么小括号可以省略
如果方法体当中只有一句代码,那么大括号可以省略
如果方法体中只有一条语句,其是return语句,那么大括号可以省略,且去掉return关键字。
3.变量捕获
3.1 匿名内部类的变量捕获
class Test { public void func(){ System.out.println("func()"); } } public class Demo { public static void main(String[] args) { int a=100; new Test(){ @Override public void func() { System.out.println("我是内部类,且重写了func这个方法!"); System.out.println("捕获到变量a=="+a); } }; } }
在上述代码中的变量a就是捕获的变量。这个变量要么是被final修饰,如果不被final修饰需要确保在使用之前没有被修改。如下便是错误代码:
public class Demo { public static void main(String[] args) { int a=100; new Test(){ @Override public void func() { a=99; System.out.println("我是内部类,且重写了func这个方法!"); System.out.println("捕获到变量a=="+a); } }; } }
该代码直接编译报错。
3.2 Lambda的变量捕获
@FunctionalInterface interface NoParameterNoReturn { void test(); } public static void main(String[] args) { int a=10; NoParameterNoReturn noParameterNoReturn=()->{ //a=99; error System.out.println("捕获变量:"+a); }; noParameterNoReturn.test(); }
4.总结
接口并不能直接实例化,但可以通过匿名内部类(实现该接口的匿名类)来不借助类去实现接口中的方法,但Lambda表达式是匿名内部类的更进一步,它可以直接实现接口中的方法(不需要借助类,也不需要重写抽象方法)。
Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读
优点:
1.代码简洁,开发迅速
2.方便函数式编程
3.非常容易进行并行计算
4.Java中引入了Lambda,改善了集合操作
缺点:
1.代码可读性变差
2.在非并行计算中,很多计算未必有传统的for性能高
3.不容易进行调试