Lambda相当于就是一个匿名方法,其在代替匿名内部类创建对象的时候,Lambda表达式代码块会代替实现抽象方法的方法体
Lambda表达式的目标类型必须是“函数式接口(FunctionalInterface)”。函数式接口只能包含一个抽象方法接口。函数式接口可以包含多个默认方法、类方法、但只能一个抽象方法
函数式接口
- 有且只有一个没有default关键字修饰的接口
可以多个default关键字的抽象方法、类方法、变量
语法组成元素
- 形参列表。形参可以省略数据类型。若只有一个参数,可以将圆括号省略
- 箭头(->)
- 代码块。如果只有一条语句,Lambda表达式可以省略花括号。代码块只能有一条return语句,并且可以省略return关键字
1 | public class Lam { |
Lambda的代码块中就是用来实现接口的抽象方法,而且有且只能有一个。若有default关键字的抽象方法是不属于函数式接口(FunctionalInterface)
存在@FunctionalInterface注解的一定是函数式接口,没有@FunctionalInterface不一定就不是函数式接口
1 | public class Lam { |
方法引用与构造器引用
种类 | 示例 | 说明 | 对应的Lambda表达式 |
---|---|---|---|
引用类方法 | 类名::类方法 | 函数式接口中实现的方法的全部参数都传递给类方法作为参数 | (a,b,…)->类名.类方法(a,b,…) |
特定对象的实例方法 | 对象::实例方法 | 函数式接口中实现的方法的全部参数都传递给类方法作为参数 | (a,b,…)->对象.实例方法(a,b,…) |
引用某类对象的实例方法 | 类名::实例方法 | 函数式接口中实现的方法第一个参数作为调用者,之后的参数都作为方法的参数 | (a,b,…)->a.实例方法(b,…) |
引用构造方法 | 类名::new | 函数式接口中实现的方法的全部参数都传递给类方法作为参数 | (a,b,…)->类名.new(a,b,…) |
使用::这种方式,抽象方法肯定是存在参数的
其实上面三类可以归为一类来看待,这是形式不同而已
1 | public class Lam { |
引用构造方法
1 | public class Lam { |
等价于
1 | public class Lam { |
Lambda表达式与匿名函数的异同点
同
- Lambda表达式与匿名内部类一样,都可以直接访问“effectivly final”的局部变量,以及外部类的成员变量(包括实例变量和类变量)
- Lambda表达式创建的对象与匿名内部类生成的对象一样,都可以直接调用从接口中继承的默认方法
异
- 匿名内部类可以为任意接口创建实例——不管接口包含多少抽象方法,只要匿名内部类实现所有的抽象方法即可;但Lambda表达式只能为函数式接口创建实例
- 匿名内部类可以为抽象类甚至普通类创建实例;但Lambda表达式只能为函数式接口创建实例
- 匿名内部类实现的抽象方法的方法体运行调用接口中定义的默认方法;但Lambda表达式的代码块不允许调用接口中定义的默认方法