Lambda表达式

来源:互联网 发布:我的世界java路径 编辑:程序博客网 时间:2024/06/17 19:58

Lambda表达式支持将代码块作为方法参数,lambda表达式允许使用更简洁的代码来创建实现了只有一个抽象方法的接口(函数式接口)的类的实例:

package ech0;interface Demo{    void show();}public class LambdaDemo {    public static void main(String[] args) {        Demo demo = ()->System.out.println("this is a demo~");        demo.show();        System.out.println(demo.getClass());    }}

需要注意的是 lambda表达式的类型 必须是 函数式接口 (functional interface) ,即 只包含一个抽象方法的接口。函数式接口可以包含很多个默认方法、类方法、但只能声明一个抽象方法。

lambda 表达式主要由三部分构成:

①形参列表。形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。

②箭头 ->

③代码块。如果只包含一条语句,则可以省略代码块的花括号。如果代码块中只有一条return语句,甚至可以省略return关键字。lambda表达式需要返回值(实现的接口中的抽象方法有返回值),而代码块中仅有一条省略了return的语句,那么lambda表达式会自动返回这条语句的值。

package ech0;interface Eatable {    void taste();}interface Flyable {    void fly(String animal);}interface Addable {    int add(int a, int b);}public class LambdaTest {    public void test(Eatable eatable) {        System.out.println("Eatable:     " + eatable);        eatable.taste();    }    public void test(Flyable flyable) {        System.out.println("Flyable:     " + flyable);        flyable.fly("dog");    }    public void test(Addable addable) {        System.out.println("Addable:     " + addable);        System.out.println("22 and 33 is " + addable.add(22, 33));    }    public static void main(String[] args) {        LambdaTest lambdaTest = new LambdaTest();        lambdaTest.test(() // 代码块中只有一条语句,可以省略花括号                -> System.out.println("apple is delicious!")        );        lambdaTest.test(weather -> {//只有一个参数,可以省略参数列表的圆括号            System.out.println(weather + " can not fly~");        });        lambdaTest.test((a, b) -> a + b);//lambda表达式需要返回值,而且代码块只有一条语句,故可以省略花括号和return关键字。    }}

为了保证lambda表达式的目标类型是一个明确的函数式接口,有以下三种常见的方式:

①将lambda表达式赋值给函数式接口类型的变量。

②将lambda表达式作为函数式接口类型的参数传递给某个方法。

③使用函数式接口对lambda表达式进行强制类型转换。

Object object = (Runnable) ()->System.out.println("this is a new runnable instance~"); //相当于创建了一个实现了runnable接口的类的实例

同样的Lambda表达式的目标类型完全可能是变化的,唯一的要求是Lambda表达式实现的匿名方法与目标类型中的唯一抽象方法有相同的形参列表。

例如定义了如下接口:

interface  NewRunnable{    void go();}
那么之前强制转换为runnable类型的lambda表达式也可以转换为NewRunnable类型:

Object object = (NewRunnable) ()->System.out.println("this is a new runnable instance~");


Lambda表达式与匿名内部类的相似之处:

①Lambda表达式与匿名内部类一样都可以直接访问“effectively final”的局部变量,以及外部类的成员变量(包括实例变量与类变量)

“effectively final” 即对于访问的局部变量,相当于有一个隐式的final修饰

②Lambda表达式创建的对象与匿名内部类生成的对象一样,都可以直接调用从接口中继承的默认方法

不同点:

①匿名内部类可以为任意接口,抽象类甚至普通类创建实例,但Lambda表达式只能为函数式接口创建实例

②匿名内部类实现的抽象方法体允许调用接口中默认方法,但Lambda表达式的代码块不允许调用接口中定义的默认方法。


0 0
原创粉丝点击