Lambda表达式

Lambda表达式是Java 8的重要更新。它支持将代码块作为方法的参数。Lamnda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(即函数式接口)的实例。

Lambda表达式的主要作用是代替匿名内部类的烦琐语法代码。例:

有如下接口Command:

public interface Command{
    void process(int[] array);
}

ProcessArray类下有方法process:

class ProcaeeArray{
    public void process(int[] array, Command c){
        c.process(int[] array);
    }
}

由上可见:ProcessArray类的process方法需要借助Command接口来对数组array进行操作。这种需求来源于需要对数组进行不同的操作,可以使用Command接口的不同实现类来完成。这种设计方式成为命令模式。

当我们在实际使用的时候,有可能Command接口的实现类只用到一次,这时就可以使用匿名内部类来实现简化操作:

public class Test{
    public static void main(String[] args){
        ProcessArray pa = new ProcessArray();
        int[] target = {1,2,3,4};
        pa.process(target, new Command(){
                int sum = 0;
                for(int tmp : target)
                    sum +=target;
                System.out.println("数组元素的和是"+sum);
        });
    }
}

这样我们就能通过不同的匿名内部类来对数组进行不同的操作。

而Lambda用来简化匿名内部类。以上的程序可以写成:

public class Test{
    public static void main(String[] args){
        ProcessArray pa = new ProcessArray();
        int[] target = {1,2,3,4};
        pa.process(target, (int[] array) ->{
                int sum = 0;
                for(int tmp : target)
                    sum +=target;
                System.out.println("数组元素的和是"+sum);
        });
    }
}
由上可见:Lambda表达式由3部分组成:

1:形参列表:即例中的(int[] array)。形参列表允许省略形参类型,如果只有一个形参参数,括号也可以省略。

2:箭头:即例子中的 ->。由英文中画线和大于号组成。

3:代码块:由例子可见,代码块的内容就是原匿名内部类中方法的方法体。如果代码块只有一条语句,那么花括号可以省略。如果只有一条语句,且是return语句,那么return也可以省略,表达式自动返回值。

在此例中,Lambda表达式代表了Command实例。但在其他代码中可能需要代表Command1类型的实例、Command类型的实例。这就意味着Lambda表达式实际上会被当作类型可以随意转换的对象。到底是何种目标类型,取决于具体的代码。

但是有一点要求:即Lambda表达式的目标类型必须是:函数式接口。

函数式接口指只包含一个抽象方法的接口。Java8为函数式接口提供了@FunctionalInterface注解,它告诉编译器检查该接口必须是函数式接口,否则报错。

Lambda的代码块部分其实就对应函数式接口中的方法,形参列表部分对应方法的参数。

由于Lambda表达式当成对象,因此可以使用Lambda表达式进行赋值:

Runnable r = () -> {
    System.out.println("Lambda表达式为函数式接口对象赋值");
}                //Runnable为一个关于多线程的函数式接口

注意:目标对象必须是明确的函数式接口的实例。比如把Lambda赋值给Object类型的对象,会报错。这时需要强制类型转换:

Object obj = (Runnable)()->{
  System.out.println("接口并没有继承Object");
}        //这里需要指明一点:Runnable接口并没有继承Object类。    Lambda可以看作为一个接口的实现实例,而实例是一个类,而所有类的父类都是Object

Lambda表达式的类型可以转换,也就是相同内容的Lambda表达式可以赋值给不同的对象。

关于Lambda的简化,有方法引用和构造器引用,这里不再赘述。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值