Java的Lambda表达式
1、使用方式:Lambda表达式支持将代码块作为方法参数,运行使用简单的代码来创建只有一个抽象方法的接口的实例
使用一个完整的例子来阐述实现类、匿名内部类、Lambda表达式三者的优缺点。
//方式一:使用实现类方式
//定义一个接口
interface Command{
//抽象方法,表示一种处理方式
void process(int[] target);
}
//定义一个类实现Command接口
class PrintCommand implements Command{
//实现接口中的抽象方法
public void process(int[] target) {
for(int i:target) {
System.out.println("输出数组中的值:"+i);
}
}
}
//定义一个数组处理类---表示对数组进行处理
class ProcessArray{
public void process(int[] target,Command cmd) {
cmd.process(target);
}
}
public class test{
public static void main(String[] args) {
//创建一个数组处理类实例
ProcessArray pa=new ProcessArray();
//待处理的数组
int[] array=new int[] {1,2,3,4};
//定义一个接口变量,实际指向的是PrintCommand类的对象
Command cmd=new PrintCommand();
pa.process(target, cmd);
}
}
//方式二:使用匿名内部类方式
interface Command{
void process(int[] target);
}
class ProcessArray{
public void process(int[] target,Command cmd) {
cmd.process(target);
}
}
public class test{
public static void main(String[] args) {
ProcessArray pa=new ProcessArray();
int[] array=new int[] {1,2,3,4};
//使用匿名内部类
pa.process(target, new Command() {
public void process(int[] target) {
for(int i:target) {
System.out.println("输出数组中的值:"+i);
}
}
});
}
}
(1)与前面的实现类相比,匿名内部类的使用减少了重新定义类来实现接口的过程
interface Command{
void process(int[] target);
}
class ProcessArray{
public void process(int[] target,Command cmd) {
cmd.process(target);
}
}
public class test{
public static void main(String[] args) {
ProcessArray pa=new ProcessArray();
int[] array=new int[] {1,2,3,4};
//使用Lambda表达式
pa.process(array, (int[] target)->{ //此时int[] target的圆括号也可以省略
for(int i:target) {
System.out.println("输出数组中的值:"+i);
}
});
}
}
(2)与前面的匿名内部类相比,Lamdba表达式能够大大简化程序的语句条数,不在需要new Xxx{} 、也不需要指出重写方法的名字、也不需要给出重写方法的返回值类型,只需要给出:重写的方法括号以及括号里的形参列表即可。
2、Lambda表达式的组成部分:
(1)形参列表:直接使用接口的抽象方法的形参列表,形参类型可省略。如果形参只有一个,圆括号可以省略
(2)箭头(->)
(3)代码块:接口中抽象方法的实现代码块。如果只有一条语句,可以省略方法体的大括号{}以及一条语句后的分号、如果是一个return语句,连return语句都可以直接省略,系统默认返回这条语句的值。
//接口1
interface InterfaceA{
void taste();
}
//接口2
interface InterfaceB{
void fly(String weather);
}
//接口3
interface InterfaceC{
int add(int a,int b);
}
class LamdabTest{
//普通方法1,其方法参数是接口1的一个对象
public void eat(InterfaceA ia) {
ia.taste();
}
//普通方法2,其方法参数是接口2的一个对象
public void dry(InterfaceB ib) {
ib.fly("多云");
}
//普通方法3,其方法参数是接口3的一个对象
public void test(InterfaceC ic) {
System.out.println("1+1等于:"+ic.add(1, 1));
}
}
public class test{
public static void main(String[] args) {
LamdabTest lt=new LamdabTest();
//Lambda表达式无形参,只有一条语句,故省略花括号
lt.eat(()->System.out.println("苹果的味道很好"));
//Lambda表达式只有一个形参,因此省略圆括号和参数类型。有两条语句,不能省略花括号
lt.dry(weather->{
System.out.println("今天的天气是:"+weather);
System.out.println("我的心情很好");
});
//Lambda表达式有2个形参,不能省略圆括号。有return语句,应该是return a+b,此处省略了return
lt.test((a,b)->a+b);
}
}
对第一个表达式进行介绍:
3、Lambda表达式与匿名内部类的区别
(1)匿名内部类可以为任何接口创建实例-——不管接口中含有多少个抽象方法,只要匿名内部类全部实现即可,但是Lambda表达式只能为函数式接口创建实例
(2)匿名内部类可以为抽象类甚至是普通类创建对象,但Lambda表达式只能为函数式接口创建实例
(3)匿名内部类实现的抽象方法的方法体中运行调用接口中定义的默认方法,但Lambda表达式的代码块中不允许调用接口中定义的默认方法。