lambda表达式:
- 一个lambda表达- 式是一个带有参数的代码块
- 当你想要代码块在以后某个时间点执行时,可以使用lambda表达式
- lambda表达式可以被转换为函数式接口
- lambda表达式可以在闭包作用域中有效的访问final变量
- 方法和构造器可以引用方法或构造器,单无需调用他们
- 你现在可以向接口添加默认(default)和静态(static)方法来提供具体的实现
- 你必须解决接口中多个默认方法之间的冲突
一, 定义
lambda表达式是一段可以传递的代码,可以用来替代 runnable , onClickListener等
名称由来: 数学原理, 带有参数变量的表达式都被成为lambda表达式
二,lambda的语法:
基本语法:
(方法参数) -> 表达式
(Stirng first,String second) -> Integer.compare(first.length(), second.length())
(String first,String second) -> {
if (first.length()< second.length()) return -1;
else if (first.length() > second.length()) return 1;
else return 0;
}
() -> { for(int i = 0; i<1000; i++) doWork(); }
简写:
1,如果lambda的表达式的参数类型是可以被推导的,那么可以省略参数类型
2,如果在1的基础上,方法参数只有一个,那么可以省略括号
EventHandler<ActionEvent> listener = event ->
System.out.println("Thanks for click!");
3,永远不需要为一个lambda表达式执行返回类型,他总是会从上下文中被推导出来
三, 函数式接口:
对于只包含一个抽象方法的接口,你可以通过lambda表达式来创建该接口的对象
四,方法引用:
要传递的代码操作,已经有实现的方法了,你可以使用方法引用:
对象::实例方法
类::静态方法
以下代码:
button.setOnAction(System.out::println)
相当于:
button.setOnAction(event -> System.out.println(event))
类::实例方法 这种写法,第一个参数会成为执行方法的对象
String::compareToIgnoreCase
相当于
(x,y) -> x.compareToIgnoreCase(y)
应用:
Arrays.sort(Strings, String::compareToIgnoreCase)
可以捕获方法引用中的this参数
this::equala
等同于
x -> this.equals(x)
也可以使用 super::实例方法
构造器引用 类::new 表示
五, 变量作用域
自由变量 : 不是表达式中 参数,且没有在表达式代码中定义的变量
含有自由变量的代码块被称之为闭包
在lambda表达式中,不能更改捕获的自由变量的值
在lambda表达式中使用this关键字时,会引用创建该lambda表达式的方法的this参数,比如:
public class Application{
public void doWork() {
Runnable runner = ( ) -> {
System.out.println( this.toString() );
};
}
}
上面代码中的this.toString()是执行Application的toString方法
六,默认方法
基于java的继承机制, 要对现有的接口进行拓展新方法是非常困难的,这意味着以前实现该接口的类都需要重新实现新增的方法.
为了解决这个问题,java8允许接口包含带有具体实现的方法(默认方法)
默认方法有方法体,并且在返回值前用default关键字修饰
如果一个接口中定义了一个默认方法,而另一个(或多个)父类或接口也定义了一个同签名的方法,那么:
- 选择父类中的方法, 如果父类提供了具体的实现方法,那么接口中的对应方法会被忽略 ("类优先"规则)
- 接口冲突, 如果都是来源于接口的默认方法,那么 该类必须复写该方法
七, 接口中的静态方法
java8中,你可以为接口添加静态方法