一.何为Lambda表达式
1.1Lambda表达式作用
Lambda表达式是java8的重要更新,它支持将代码块作为方法参数,Lambda表达式允许用更简介的代码来创建一个函数式接口(只有一个抽象方法的接口)的实例。
1.2Lambda表达式语法
(arg1,arg2...)->{}
第一部分:形参列表。形参列表允许忽略形参类型,如果只有一个参数,圆括号也可以省略。
第二部分: -> 由英文的划线和大于号组成
第三部分: 代码块。Lambda表达式只有一条return语句可以省略return关键字,代码块只有一行可以省略花括弧,
1.3Lambda表达式的各种简化写法
先看以下实例代码:
interface Foot {
void walk();
}
interface Arm {
void wave(String name);
}
interface Maths {
int add(int a, int b);
}
public class SimpleLambda {
// 调用该方法需要Foot对象
public void walk(Foot e) {
System.out.println(e);
e.walk();
}
// 调用该方法需要Arm对象
public void wave(Arm f){
f.wave("主席");
}
// 调用该方法需要Math对象
public void test(Maths add) {
System.out.println("5与3的和为:" + add.add(5, 3));
}
public static void main(String[] args) {
SimpleLambda sl;
sl= new SimpleLambda ();
// Lambda表达式的代码块只有一条语句,可以省略花括号。
sl.walk(() -> System.out.println("正在走路"));// 1
// Lambda表达式的形参列表只有一个形参,省略圆括号
sl.wave(weather -> //2
{
System.out.println("握手对象是:" + weather);
});
// Lambda表达式的代码块只有一条语句,省略花括号
// 代码块中只有一条语句,即使该表达式需要返回值,也可以省略return关键字。
sl.test((a, b) -> a + b);//3
}
}
上述代码中
1 代码处使用Lambda表达式相当于不带形参的匿名方法,表达式只有一行,可以省略花括号。
2代码处使用Lambda表达式相当于一个形参的匿名方法,形参只有一个,可以省略圆括号。
3代码处使用Lambda表达式只有一行,省略return 关键字,并将这行语句当作返回值
二.函数式接口与Lambda表达式
2.1何为函数式接口
函数式接口:只包含一个抽象方法的接口,但是函数式接口可以包含多个默认方法,类方法。(java8中接口支持建立默认方法,和类方法)
2.2Lambda表达式的限制
Lambda表达式的目标类型必须明确是函数式接口。
由于Lambda表达式只能实现一个方法,所以lambda表达式只能为函数式接口创建对象。
2.3确保Lambda表达式的目标类型是函数式接口的常用方法
将Lambda表达式当作函数式接口类型的参数传给方法 .
使用函数式接口类型对Lambda表达式进行强转.
将Lambda表达式赋给函数式接口类型的变量.
三.Lambda表达式方法引用和构造器引用
3.1引用类方法
Lambda表达式:(a,b...)->类名.类方法(a,b...)
简化:类名::类方法
说明:函数式接口被实现方法的全部参数传递给该方法.
3.2引用特定对象的实例方法
Lambda表达式:(a,b...)->对象.实例方法(a,b...)
简化:对象::实例方法
说明:函数式接口被实现方法的全部参数传递给该方法.
3.3引用某类对象的实例方法
Lambda表达式:(a,b,c...)->a.实例方法(b,c...)
说明:a参数作为调用者,a参数之后全部参数传递给该方法作为参数
3.4引用构造器
Lambda表达式:(a,b...)->new 类名(a,b...)
简化:类名::new
说明:函数式接口被实现方法的全部参数传递给构造器
3.5实例代码
import javax.swing.*;
public class LambdaMethod{
public static void main(String[] args){
//1引用类方法
//常规lambda表达式
Test1 test11= from->Integer.valueOf(from);
//引用类方法的简化方式 类名::类方法
//函数式接口中被实现方法的全部参数传给该方法作为参数
Test1 test12=Integer::valueOf;
Integer val=test11.convert("99");
Integer val2=test12.convert("88");
System.out.println("传统lambda表达式:"+val);
System.out.println("简化lambda表达式(类名.类方法):"+val2);
//2引用特定对象的实例方法
//常规lambda表达式
Test1 test13=from -> "lambda表达式测试".indexOf(from);
Integer value=test13.convert("表达式");
System.out.println(value);
//引用特定对象的实例方法的简化方式 特定实例::实例方法
//函数式接口中被实现方法的全部参数传给该方法作为参数
Test1 test14="lambda表达式测试"::indexOf;
Integer value2=test14.convert("表达式");
System.out.println(value);
//3引用某类对象的实例方法
//常规lambda表达式 创建接口对象
Test2 test21=(a,b,c)->a.replaceAll(b, c);
String result=test21.test("lambda表达式测试","测试","检验");
System.out.println(result);
//方法引用代替lambda表达式:引用对象的实例方法
//函数式接口被实现方法的第一个参数作为调用者
//后面参数作为全部参数传递给该方法作为参数;
Test2 test22=String::replaceAll;
String result2=test22.test("引用对象的实例方法lambda表达式简化:","测试","检验"<span style="color:#008000;"></span>);
System.out.println(result2);
//4引用构造器
//普通lambda表达式作为对象
Test3 test31=(String title)->new JFrame(title);
JFrame jf=test31.win("我的窗口");
System.out.println(jf);
//构造器代替lambda表达式
//函数式接口被实现方法的第一个参数作为调用者
Test3 test32=JFrame::new;
JFrame jf2=test31.win("我的窗口2");
System.out.println(jf2);
}
}
@FunctionalInterface
interface Test1{
Integer convert(String from);
}
@FunctionalInterface
interface Test2{
String test(String a ,String b, String c);
}
@FunctionalInterface
interface Test3{
JFrame win(String title);
}
四.Lambda表达式与匿名内部类
4.1相同点
Lambda表达式是匿名内部类的一种简化,可以部分取代匿名内部类的作用
Lambda表达式和匿名内部类异样,可以访问final局部变量,以及外部的成员变量
Lambda表达式创建的对象和匿名内部类生成的对象一样,都可以调用从接口中继承的default方法.
4.2不同点
匿名内部类可以为任意接口创建实例(不管接口有多少抽象方法,只需实现所有抽象方法),匿名内部类可以为任意抽象类创建实例,Lambda表达式只能为函数式接口创建实例
匿名内部类实现的抽象方法中允许调用接口中定义的default方法,但是Lambda表达式的代码块不允许调用接口中定义的default方法
五.总结
Lambda表达式就是使用简洁的语法来创建函数式接口的实例----这种语法可以节省匿名内部类创建的繁琐语法.