用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字节码文件,对应的字节码会在运行的时候动态生成。