14.1 lambda表达式
14.1.1lambda表达式简介
lambda表达式可以用非常少的代码实现抽象方法。lambda表达式不能独立执行,因此必须实现通数式接口,并且会返回一个函数式接口的对象。lambda表达式的语法非常特殊,语法格式如下:
()->结果表达式
参数->结果表达式
(参数1,参数2……,参数n)->结果表达式
误区警示:“->”符号是由英文状态下的“-”和“>”组成的,符号之间没有空格。
14.1.2 lambda表达式实现函数式接口
1、函数式接口
interface MyInterface{
void method();}
2、lambda表达式实现无参抽象方法
很多函数式接口的抽放方法是无参数的 ,如线程接口Runnable接口只有一个run()方法,这样的无参抽象方法在lambda表达式中使用“()”表示。
【例14.1】使用lambda表达式实现打招呼接口
3、lambda表达式实现有参抽象方法
抽象方法中有一个或多个参数的函数式接口也是很常见的,lambda表达式中可以用“(a1,a2,a3)”的方法表示有参抽象方法,圆括号里标识符对应抽象方法的参数。
【例14.2】使用lambda表达式做加法计算
4、lambda表达式使用代码块
当函数式接口的抽象方法需要实现复杂逻辑而不是返回一个简单的表达式的化,就需要在lambda表达式中使用代码快。
【例14.3】使用lambda表达式为考试 成绩分类
14.1.3 lambda表达式调用外部变量
lambda 表达式除了可以调用定义好的参数,还可以调用表达式以外的变量。但是,这些外部的变量有些可以被更改,有些则不能。例如,lambda表达式无法更改局部变量的值,但是却可以更改外部类的成员变量(也可以叫作类属性)的值。
1. lambda 表达式无法更改局部变量
局部变量在lambda 表达式中默认被定义为final(静态)的,也就是说,lambda表达式只能调用局部变量,却不能改变其值。
2.lambda表达式可以更改类成员变量
类成员变量是在lambda表达式中不是被final修饰的,所有lambda表达式可以改变其值。
14.1.4lambda表达式与异常处理
很多接口的抽象方法为了保证程序的安全性,会在定义时就抛出异常。但是lambda表达式中并没有抛出异常的语法,这是因为lambda表达式会默认抛出抽象方法原有异常,当此方法被调用时则需要进行异常处理。
14.2 方法的引用
lambda 表达式还添加了一类新语法,用来引用方法,也就是说方法也可以作为一个对象被调用。根据不同的方法类型,方法的引用包括引用静态方法、引用成员方法和引用构造方法等。
14.2.1 引用静态方法
引用静态方法的语法如下:
类名::静态方法名;
这个语法中出现了一个新的操作符“::”,这是由两个英文冒号组成的操作符,冒号之间没有空格。这个操作符左边表示方法所属的类名,右边是方法名。需要注意的是,这个语法中方法名是没有圆括号的。
14.2.2引用成员方法
语法如下:
对象名::成员方法名
与引用静态方法语法不同,这里操作符左侧的必须是一个对象名,而不是类名。这种语法也可以达到抽象方法按照类成员方法逻辑来实现的目的。
14.2.3 引用带泛型的方法
泛型是java开发经常使用到的功能,"..”操泛型是Java开发经常使用到的功能,作符支持引用带泛型的方法。除方法外操作符也支持引用带泛型的类。
14.2.4 引用构造方法
lambda表达式有3种引用构造方法的语法,分别是引用无参构造方法、引用有参构造方法和引用数组构造方法,下面分别进行讲解
1.引用无参构造方法
引用构造方法的语法如下
类名:new
因为构造方法与类名相同,如果操作符左右都写类名,会让操作符误以为是在引用与类名相同的静态方法,这样会导致程序出现Bug,所以引用构造方法的语法使用了new关键字。操作符右侧的写new关键字,表示引用构造方法。
这个语法有一点要注意: new关键字之后没有圆括号,也没有参数的定义。如果类中既有无参构造方法,又有有参构造方法,使用引用构造方法语法后,究竟哪一个构造方法被引用了呢,
2.引用有参构造方法
引用有参构造方法的语法与引用无参构造方法一样。区别就是函数式接口的抽象方法是有参
数的。
3.引用数组构造方法
Java开发可能出现这样一和特殊场景:把数组类型当作泛型。如果方法返回值是泛型,在这种特殊场景下,方法就应该返回一个数组类型的结果。如果要求抽象方法既引用构造方法又要返回数组类型结果,这种场景下抽象方法的参数就有了另外一个含义: 数组个数。抽象方法的参数可以决定返回的数组长度,但数组中的元素并不是有值的,还需要再次赋值。引用数组构造方法的语法也会有所不同,语法如下:
类名[::new
14.3流处理
流处理有点类似数据库的SQL语句,可以执行非常复杂的过滤、映射、查找和收集功能,并且代码量很少。唯一的缺点是代码可读性不高,如果开发者基础不好,可能会看不懂流API所表达的含义。
为了能让读者更好地理解流API的处理过程和结果,本节先创建一个公共类Employee员工类。员工类包含员工的姓名、年龄、薪资、性别和部门属性,并给这些属性提供了getter方法。重写toString0可以方便查看员工对象的所有信息。公共类提供了一个静态方法getEmpList0,这个方法已经创建好了一些员工对象,然后将这些员工封装成一个集合并返回。本节将重点对这些员工数据进行流处理。