Lambda表达式

我们知道对于Java变量可以赋给其一个值,而如果想将"一块代码(一个完整的方法)"赋给一个Java变量,如下所示,怎么做呢?

很显然,这个并不是一个很简洁的写法,我们采用Java8的Lambada表达式来实现,那么如何简化呢

我们采用Java8的Lambada表达式来实现:整个过程去掉修饰符(public等)、去掉函数的名字(因为已经赋给变量,变量知道此方法名--往后知道抽象方法唯一,不需要方法名了)、去掉返回值类型(编译器可以推断)、去掉参数类型(编译器可以推断参数类型)

所有的Lambada的类型都是一个接口,而Lambada表达式本身("那段代码")就是一个接口的实现,这是理解Lambada的一个关键所在,理解上可以这样认为:Lambada表达式就是产生一个实现接口中唯一的抽象方法的子实现类的对象。

函数式接口:接口中只有一个需要被实现的抽象函数

说明:为了避免后来的人在接口中增加新的接口函数,导致其有多个接口函数需要被实现,变成非函数式接口,引入了一个新的Annotation(注解):@FunctionalInterface。可以把他它放在一个接口前,表示这个接口是一个函数式接口,加上它的接口不会被编译,如果加上此标记就不能再添加其他的抽象方法,否则会报错。它有点像@Override,都是声明了一种使用意图,避免你把它用错。

自定义函数式接口


测试

总结:lambda表达式本质是匿名方法

 在Java 8中有一个函数式接口的包,里面定义了大量可能用到的函数式接口(java.util.function)

->操作符

Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “ ->”,该操作符被称为 Lambda 操作符或箭头操作符。它将 Lambda 分为两个部分:

即:(参数列表)—>{express或statements}

左侧: 指定了 Lambda 表达式需要的方法参数列表←→右侧: 指定了 Lambda 体,即 Lambda 表达式要执行的功能

使用说明

(1)一个 Lambda 表达式可以有零个或多个参数,参数的类型既可以明确声明,也可以根据上下文来推断

(2)圆括号内,方法参数列表之间用逗号相隔

(3)当只有一个参数,且其类型可推导时,圆括号()可省略

(4)Lambda 表达式的主体可包含零条或多条语句,如果 Lambda 表达式的主体只有一条语句,花括号{}可省略,如果有返回值,return也可以省略,同时body中的“;”也可以省略。匿名函数的返回类型与该主体表达式一致

(5)如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

匿名内部类作为参数传递和Lamada表达式作为参数传递

匿名内部类作为参数传递

Lambada表达式作为参数传递

方法引用

概念:方法引用其实是Lambda表达式的另一种写法,当要传递给Lambda体的操作已经有实现的方法了,可以使用方法引用。

语法:使用操作符 “ ::” 将方法名和对象或类的名字分隔开来

几种常见形式

        (1)类名::静态方法

        (2)对象::实例方法

        (3)类名::实例方法

注意:

 *  1. Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保存一致

 * 2.若Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method;不管怎么说,实质还是抽象方法的实现

对比:相比而言省略参数列表,是因为二者的类型一致,主要凸显方法(重重之重!!)

以下举几个例子:


构造器引用

概念:与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽象方法的参数列表一致!

格式:ClassName:: new

注意:需要调用的构造器方法与函数式接口中抽象方法的参数列表保持一致

应用:自定义一个标记接口MyInterface,返回值类型为自定义类MyClass

测试类


你可能感兴趣的:(Lambda表达式)