用Lambda表达式用来表示匿名函数,意思是没有函数名字的函数。

 

()->{} 定义并创建了一个接口的实例。

() 定义方法参数。不需要声明参数类型。如果只有一个参数,可以省略()。

{} 定义方法体。如果只有一行,则可以省略{}。

 

Lambda表达式也叫函数式编程,对应命令式编程。

注意,要求该接口只有一个抽象方法。可以在接口定义增加注解@FunctionalInterface,声明该接口是函数式接口。

 

例子:new Thread(() -> System.out.println("hello"));

等价于:

Runnable runnable = () -> System.out.println("hello");

Thread thread = new Thread(runnable);

显然,由JDK判断() -> System.out.println("hello")实现的是Runnable接口。

为什么需要Lambda表达式

让代码更简洁。Lambda表达式可以使用非常少的代码实现抽象接口(函数式接口)。

Lambda表达式是某个函数式接口的具体实现,并且会返回一个函数式接口的对象。

 

在某些业务场景,接口是固定的,但是实现接口的具体实例只是“临时”的。不需要知道具体实例的类名(所以也叫匿名类),而方法名、参数名和返回值在接口已经定义,也就不需要这个临时的实现类再重复这些代码。

 

缺点是不如命令式编程容易调试。

注意,所有的Lambda表达式都可以转换为命令式编程吗?

 

为什么需要函数式接口

Lambda表达式调用外部变量

当在某个方法中定义Lambda表达式时,Lambda表达式不可调用该方法的参数或者局部变量。

Lambda表达式可以调用该方法所在类的成员变量和成员方法。

Lambda表达式与异常处理

在函数式接口的方法定义需抛出的异常。

在Lambda表达式的定义中抛出异常。

在调用Lambda表达式的位置处理异常。

 

Lambda表达式有哪些常见写法?

(String s, String t) -> {return s.length – t.length;}

左侧()代表方法的参数,右侧{}代表方法的实现。

而整体的() -> {}代表的是一个函数式接口的实现。

其中,如果方法体有多条语句,则用{}。如果只有一条语句,可以省略{}和return。即s.length – t.length;就是方法的返回值。

(String s, String t) -> s.length – t.length;

如果根据上下文可以推导出方法参数的类型,则可以省略类型的声明。

(s, t) -> s.length – t.length;

如果只有一个方法参数,则可以省略()。

S -> System.out.println(s);

如果没有方法参数,可以直接写()。

() -> System.out.println(“hello”);

()表示对应的函数式接口的方法没有参数。不需要声明返回值的类型,因为总是可以通过上下文推导出。

Lambda表达式和引用方法

在定义Lambda表达式时的语法。

1.引用静态方法

比如类名::静态方法

2.引用成员方法

对象::成员方法

3.引用带泛型的方法

比如类名::<Integer>静态方法

4.引用构造方法

类名::new


函数式编程

避免使用大量的重复代码来实现司空见惯的功能。

 

一个函数可以作为参数,传递给另外一个函数。

一个函数可以作为返回值。

一个函数可以赋值给一个变量。

 

在函数式编程中,几乎所有传递的对象都不会被轻易修改。

由于对象处于不变的状态,因此函数式编程更加易于并行。甚至完全不用担心线程安全的问题。

 

Lambda表达式是函数式编程和核心。

Lambda表达式即匿名函数,它是一段没有函数名的函数体,可以作为参数直接传递给相关的调用者。

 

Lambda表达式和匿名内部类的区别

一、所属类型不同

匿名内部类:可以是接口,也可以是抽象类,还可以使用具体类。

lambda表达式:只能是接口。

二、使用限制不同

1.如果接口中有些仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类。

2.如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式。

三、实现原理不同

匿名内部类:编译之后,产生一个单独的.class字节码文件。

lambda表达式:编译之后,没有单独的.class字节码文件,对应的字节码会在运行的时候动态生成。