一、什么是 lambda 表达式
Java8 是我们使用最广泛的稳定 Java 版本,lambda 就是其中最引人瞩目的新特性。lambda 是一种闭包,它允许把函数当做参数来使用,是面向函数式编程的思想,可以使代码看起来更加简洁。是不是听得一脸懵逼?我举个栗子你就明白了。
有 lambda 之后,我们就用 lambda 写: image.png
我们应该知道,实现线程有两种方法,一是继承 Thread 类,二是实现 Runnable 接口。那这里采用的就是后者,后者是一个函数式接口。 1.1 函数式接口 image.png
从 Runnable 源码可以看到,它是一个 ** 函数式接口。** 这类接口的特点是:用 @FunctionalInterface 注解修饰(主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错),有且只有一个抽象方法。在原生 JDk 中的这类接口就可以使用 lambda 表达式。
上面的概念提到,把函数当做参数来使用。上面的 lambda 例子中,Thread 类的参数就是一个 Runnable 接口,lambda 就是实现这个接口并把它当做参数使用。所以上面的 () -> System.out.println ("lambda 写法") 就是一个整个 lambda 表达式的参数(注意与后面的方法参数区分开,后面会讲)。细品加粗这句话,可以总结出,lambda 表达式就是创建某个类的函数式接口的实例对象。 如: image.png二、为什么需要 lambda 表达式
明白了什么是 lambda 表达式,那为什么要使用它呢?注意到使用 lambda 创建线程的时候,我们并不关心接口名,方法名,参数名。我们只关注他的参数类型,参数个数,返回值。所以原因就是简化代码,提高可读性。
三、如何使用 lambda 表达式
image.png
lambda 语法例子
具体解释,如上图。此外,lambda 语法注意点:
可选类型声明:方法参数不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但无参数或多个参数需要定义圆括号。
可选的大括号:如果具体实现方法只有一个语句,就不需要使用中括号 {}。
可选的返回关键字:如果具体实现方法只有一个表达式,则编译器会自动返回值,如果有多个表达式则,中括号需要指定明表达式返回了一个数值。
看一个简单的方法引用例子: image.png Consumer 函数式接口源码: image.png
你可能有点懵,为什么可以这样写?别急我们分析一波:Consumer是一个函数式接口,抽象方法是 void accept (T t),参数都是 T。那我们现在有这样一个需求,我想利用这个接口的抽象方法,做一下控制台打印。正常情况下,我们需要实现这个接口,实现它的抽象方法,来实现这个需求: image.png 实现之后,这个抽象方法变具体了。作用就是控制台打印,那就意味着抽象方法刚好可以用实际方法:System.out.println (s) 来实现,所以我们可以使用方法引用。
总结:函数式接口的抽象方法实现恰好可以通过调用一个实际方法来实现时,就可以用方法引用。
方法引用的三种形式: image.png 自定义一个方法类: image.png 测试用例: image.png 输出结果: image.png 3.4 构造器引用 image.png 3.5 变量作用域lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。 image.png 变量不声明为 final ,导致可以修改外部变量报错: image.png 此外,在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量 image.png
更多的java基础知识+峮:1080621881
网友评论