Spring 5企业级开发实战
上QQ阅读APP看书,第一时间看更新

5.1 Lambda表达式

5.1.1 Lambda表达式初探

Lambda表达式,也可称为闭包,是Java 8最重要的新特性之一。Lambda允许把函数作为一个方法的参数使用。使用Lambda表达式可以使代码变得更加简洁紧凑。其实Lambda表达式的本质只是一个“语法糖”,由编译器推断并转换为常规的代码,因此可以使用更少的代码来实现同样的功能。

Lambda表达式的语法格式如下:

     (parameters) -> expression
     (parameters) ->{ statements; }

Lambda表达式的一些重要特征如下。

• 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

• 可选的参数圆括号:当只有一个参数时,无须定义圆括号,但如果有多个参数则需要定义圆括号。

• 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

• 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值。

下面是Lambda表达式常见的书写方式:

     // 不需要参数,返回值为 5
     () -> 5
     // 接收一个参数(数值类型),返回其2倍的值
     x -> 2 * x
     // 接受两个参数(数值类型),并返回两者的差值
     (x, y) -> x – y
     // 接收两个int型参数,返回两者的和
     (int x, int y) -> x + y
     // 接受一个 string 对象,并在控制台打印,不返回任何值
     (String s) -> System.out.print(s)

下面将通过案例展示Lambda表达式的使用:

运行测试代码得到如下测试结果:

     100 + 50 = 150
     100 - 50 = 50
     100 x 50 = 5000
     100 / 50 = 2

5.1.2 Lambda表达式作用域

可以直接在Lambda表达式中访问外层的局部变量,但在Lambda表达式内部不能修改定义在Lambda表达式外部的局部变量,否则会编译错误。Lambda表达式的局部变量可以不用声明为final,但是必须不可被后面的代码修改(即隐性的具有final的语义)。在Lambda表达式当中不允许声明一个与外部变量同名的参数或者局部变量。

如果将today = "2018/10/12"这一行代码取消注释,将会出现Variable used in lambda expression should be final or effectively final编译错误。如果将String myName = "Java"这一行代码取消注释,也会出现编译错误。

执行以上代码,得到执行结果如下:

     Hello World !

5.1.3 在线程中使用Lambda表达式

下面通过案例代码将不使用Lambda表达式和使用Lambda表达式时的简洁代码进行对比:

执行测试代码,得到执行结果如下:

     线程1
     线程2

5.1.4 在集合中使用Lambda表达式

经常需要在集合中对集合中的元素进行排序。下面使用一个集合元素排序的案例对Lambda表达式的使用进行阐释。首先定义一个Person类,其中包含两个属性,姓名name和年龄age。

在测试代码中,对不使用Lambda表达式和使用Lambda表达式的场景进行对比。

执行测试代码,得到如下测试结果:

     [张三:20, 李四:22, 王五:26]
     [王五:26, 李四:22, 张三:20]
     [张三:20, 李四:22, 王五:26]

5.1.5 在Stream中使用Lambda表达式

Stream是对集合的包装,通常和Lambda表达式一起使用。使用Lambda表达式可以支持许多操作,如map、filter、limit、sorted、count、min、max、sum和collect等等。在接下来的案例中,将使用Lambda表达式和Stream对Person集合进行排序。

在测试案例中,将personList对象转换为Stream对象,并配合Lambda表达式对其进行排序。执行代码,可得到如下测试结果:

     [张三:24, 赵六:26, 王五:28, 赵七:30, 李四:32]