java Lambda表达式的使用心得
lambda表达式的心得
如题,因为博主也是最近才接触到lambda表达式的(ps 在这里汗颜一会)。我并不会讲解它的原理,诚然任何一件事物如果理解原理的话,使用它必将更加容易。但博主在学习的时候,大多数时候都是学会怎么用,然后在细究原理。就像你骑自行车之前,难道首先还要研究自行车的原理么?
首先lambda表达式的最简单应用如下
lambda表达式法
string lam= "初次相识lambda"; new thread(() -> system.out.println(lam)).start();
传统方法
string tradition="传统方法"; new thread(new runnable() { @override public void run() { system.out.println(tradition); } }).start();
输出结果
很简洁有没有?省略了好多代码是不是,在这里 你可以发现”,lambda表达式和在thread创建一个匿名类的作用是一样。我们可以这样认为lambda表达式本身代表了一个匿名类。
这就是lambda最大的作用,当然lambda表达式只能创建接口interface对象。 创建类是不行的,抽象类也是不行的 ,只要是类都是不行的。
首先,我定义了一个自定义的接口,可以用来测试
@functionalinterface public interface lam { //lambda表达式调用的方法 void bda(); //接口的默认方法 default void test(){ system.out.println("我是默认的方法"); }; //接口的静态方法 static void test1(){ system.out.println("我是静态方法"); } }
使用lambda表达式 你首先要知道的
1.lambda表达式只能是接口 interface的创建(ps从上面的例子可以看出来,runnable是接口,可以查看源代码),并且这个接口只能包含一个方法(除了default方法和static方法)。在接口中创建default方法和static方法都必须要实现方法体如下图
2.如果你用lambda表达式来创建类 class,则会出现以下错误 ”target type of a lambda conversion must be an interface“如果你怕自己的定义的接口不符合lambda表达式的规范 ,你可以在接口interfaca 上面添加注解@functionalinterface
3.lambda表达式的规范表示格式 (parameters) ->{ statements; }。在某些时刻,你还可以简化这个格式
//接口定义的方法无参数时候,并且你想要执行操作也只有一句代码的时候,lambda会自动返回一句代码,并且可以不用加{} lam lam1=()->system.out.println("无参数");
你可以发现后面的大括号{ }没了,这是因为后面代码如果只有一句的话,是可以省略{ } 的
我们把lam接口定义的调用方法参数修改一下,多出了一个string类型的形参s
//lambda表达式调用的方法 void bda(string s);
这时候 我们如果使用lambda表达式,则可以这样
//接口定义的方法有参数时候,并且你想要执行的操作也只有一句代码的时候 lam lam1=e->system.out.println(e);//这一句还有简化版本 lam lam1=system.out::println; lam1.bda("4556");
你又会发现,前面的()中括号也没了,这是因为当参数只有一个的时候,是可以省略()的。
当然也有你要执行很多代码的时候,那这时候可以这样
//接口定义的方法有参数时候,并且你想要执行的操作有很多句代码的时候 lam lam1 = (string e) -> { string a = e + "add"; system.out.println(a); }; lam1.bda("test+");
输出结果如下
当然你还会问lambda表达式能不能返回东西呢?这是肯定能的,首先我们再把上面的lam接口方法修改一下
//lambda表达式调用的方法 string bda(string s);
让bda方法返回一个string值,这次如果我们用lambda的话
//接口定义的方法有返回值的时候 lam lam1=s ->{system.out.println(s);return "我是返回的数据";}; lam1.bda("test1"); system.out.println(lam1.bda("test2"));
运行的结果:
总结 lambda表达式 就是用来创建一个匿名的接口对象,即 它本身就是一个接口的匿名实例。只不过这个接口 有一些条件限制。
lambda表达式的技巧
lambda表达式只能用来简化仅包含一个public方法的接口的创建
规则
- 1.只能是接口
- 否则报:target type of a lambda conversion must be an interface
- 2.只能有一个public方法
- 否则报:multiple non-overriding abstract methods found ainterface
- 或ainterface is not a functional interface
括号形式
testa((int i, int j) -> {});参数要与接口一致
public class go { public static void main(string a[]) { //正确示范 testa((int i, int j) -> {}); //错误示范:multiple non-overriding abstract methods found xxx;只能有一个public方法 testb((int i, int j) -> {}); //错误示范:target type of a lambda conversion must be an interface;只能是接口 testc((int i, int j) -> {}); } public static void testa(ainterface t) { } public static void testc(cinterface t) {} public static void testb(binterface t) {} interface ainterface { void xxx(int i, int j); } interface binterface { void xxx(int i, int j); void yyy(int i, int j); } abstract class cinterface { abstract void xxx(int i, int j); } }
双冒号表达形式
- 双冒号后面必须是静态方法
- 否则报错:non-static method cannot be referenced from a static context
- 双冒号后面的方法与接口方法参数一样
- 方法与接口的权限可以不一样
- 返回类型:如果接口里面方法是void,双冒号后的方法可以任意返回类型,否则要一致
public class go { public static void main(string a[]) { //之前的写法 testa(new ainterface() { @override public void xxx(int i, int j) { } }); //正确,相对与接口里面xxx方这是改成静态和换了个名字 testa(go::mydog); //正确,加了返回类型和public换成private,也是ok testa(go::mydog2); //错误:non-static method cannot be referenced from a static context testa(go::mydog3); //这样写也是ok的。 ainterface ainterface = go::mydog; testa(ainterface); } public static void testa(ainterface t) { t.xxx(1, 2); } interface ainterface { void xxx(int i, int j); } public static boolean mydog(int i, int j) { system.out.println("mydog" + i + " & " + j); return false; } private static void mydog2(int i, int j) { system.out.println("mydo2" + i + " & " + j); } public void mydog3(int i, int j) { system.out.println("mydog3" + i + " & " + j); } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。