一、Lambda简介
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。
Lambda表达式允许把函数作为一个方法的参数(函数作为参数传递到方法中)。lambda表达式是一个可传递的代码块,可以在以后执行一次或多次,它可以传递到函数式接口。
二、Lambda 基础语法
语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。
(parameters) -> expression
或
(parameters) ->{ statements; }
Lambda 语法简化
1.简化参数类型,可以不写参数类型,但是必须所有参数都不写;
2.简化参数小括号,如果只有一个参数则可以省略参数小括号;
3.简化方法体大括号,如果方法条只有一条语句,则可以省略方法体大括号;
4.简化返回关键字,如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号及返回关键字return。
三、变量作用域
Lambda表达式只能引用标记了final的外层局部变量,即不能在Lambda内部修改定义在外层的局部变量,否则会编译报错。外层的局部变量可以不用声明为final,但是必须不可被后面的代码修改(即隐性的具有final的语义)。
在Lambda表达式中不允许声明一个与外层的局部变量同名的参数或者局部变量。
四、方法引用
方法引用通过方法的名字来指向一个方法,可以使语言的构造更紧凑简洁,减少冗余代码,方法引用使用一对冒号 :: 。
语法
方法归属者::方法名 静态方法的归属者为类名,普通方法归属者为对象。
构造器引用:它的语法是Class::new,或者更一般的Class< T >::new。
静态方法引用:它的语法是Class::static_method。
特定类的任意对象的方法引用:它的语法是Class::method。
特定对象的方法引用:它的语法是instance::method。
五、函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为 lambda 表达式。
JDK 1.8 之前已有的函数式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
JDK 1.8 新增加的函数接口:
java.util.function
java.util.function 它包含了很多类,用来支持 Java的函数式编程。
1.新注解@FunctionalInterface
Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。
提醒:加不加 @FunctionalInterface 对于接口是不是函数式接口没有影响,该注解只是提醒编译器去检查该接口是否仅包含一个抽象方法。
2.函数式接口里允许定义默认方法
函数式接口里可以包含默认方法,因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的。
实现接口后,因为默认方法不是抽象方法,所以可以不重写,但是如果开发需要,也可以重写 。如果接口中的默认方法不能满足某个实现类需要,那么实现类可以覆盖默认方法。签名跟接口default方法一致,但是不能再加default修饰符。
3.函数式接口里允许定义 java.lang.Object 里的 public 方法
函数式接口里是可以包含Object里的public方法,这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了 Object 类,包含了来自 java.lang.Object 里对这些抽象方法的实现。
4.常用函数式接口
Supplier<T>,主要方法:T get(),这是一个生产者,可以提供一个T对象。
Consumer<T>,主要方法:void accept(T),这是一个消费者,默认方法:andthen(),稍后执行。
Predicate<T>,主要方法:boolean test(T t),这是一个判断者,接受一个输入参数 T,返回一个布尔值结果。默认方法:and():且,or():或,negate():非。
Function<T,R>,主要方法:R apply(T t),这是一个修改者,默认方法:compose():优先执行,andThen(),稍后执行,identity():直接传自身。