Java第十四章课堂总结

lambda就是数学中的“λ”的读音,lambda表达式是基于λ演算而得名的,因为lambda抽象(lambda abstraction)表示一个匿名的函数,于是开发语言也将lambda表达式用来表示匿名函数,也就是没有函数名字的函数。C#、Python,甚至是C++都有lambda表达式语法。为了提高开发者的开发效率,并照顾“跨语言”开发者的开发习惯,Java语言也加入了lambda表达式。流处理是Java程序中一种重要的数据处理手段,它用少量的代码便可以执行复杂的数据过滤、映射、查找和收集等功能。

lambda表达式

1. lambda表达式简介

lambda表达式可以用非常少的代码实现抽象方法。lambda表达式不能独立执行,因此必须实现函数式接口,并且会返回一个函数式接口的对象。lambda表达式的语法非常特殊

() -> 结果表达式
参数 -> 结果表达式
(参数1,参数2....,参数n)-> 结果表达式

1.行实现无参方法,单独写一对圆括号表示方法无参数,操作符右侧的结果表达式表示方法的返回值。
2.行实现只有一个参数的方法,参数可以写在圆括号里,或者不写圆括号。
3.行实现多参数的方法,所有参数按顺序写在圆括号里,且圆括号不可以省略。

lambda表达式也可以实现复杂方法,将操作符右侧的结果表达式换成代码块即可

()->(代码块)
参数 ->(代码块)
(参数1,参数2....,参数n)->(代码块)

       1.行实现无参方法,方法体是操作符右侧代码块。
  2.行实现只有一个参数的方法,方法体是操作符右侧代码块。
  3.行实现多参数的方法,方法体是操作符右侧代码块。
  lambda表达式的语法非常抽象,并且有着非常强大的自动化功能,如自动识别泛型、自动数据类型转换等,这会让初学者很难掌握。如果将lambda表达式的功能归纳总结

() (代码块)
这个方法 按照 这样的代码来实现

简单总结:操作符左侧的是方法参数,操作符右侧的是方法体。

  误区警示
  “->”符号是由英文状态下的“-”和“>”组成的,符号之间没有空格

2.lambda表达式实现函数式接口

  lambda表达式可以实现函数式接口,本节将讲解函数式接口概念以及用lambda表达式实现不同类型的函数式接口。

1.函数式接口

函数式接口指的是仅包含一个抽象方法的接口,接口中的方法简单明了地说明了接口的用途,如线程接口Runnable、动作事件监听接口ActionListener等。开发者可以创建自定义的函数式接口

interface MyInterface {
void method();
}

如果接口中包含一个以上的抽象方法,则不符合函数式接口的规范,这样的接口不能用lambda表达式创建匿名对象。本章内容中所有被lambda表达式实现的接口均为函数式接口。

2.lambda表达式实现无参抽象方法

很多函数式接口的抽放方法是无参数的,如线程接口Runnable接口只有一个run()方法,这样的无参抽象方法在lambda表达式中使用“( )”表示。

【例14.1】使用lambda表达式实现打招呼接口

3.lambda表达式实现有参抽象方法

抽象方法中有一个或多个参数的函数式接口也是很常见的,lambda表达式中可以用“(a1,a2,a3)”的方法表示有参抽象方法,圆括号里标识符对应抽象方法的参数。如果抽象方法中只有一个参数,lambda表达式则可以省略圆括号。

【例14.2】使用lambda表达式做加法计算

4.lambda表达式使用代码块

当函数式接口的抽象方法需要实现复杂逻辑而不是返回一个简单的表达式的话,就需要在lambda表达式中使用代码块。lambda表达式会自动判断返回值类型是否符合抽象方法的定义。

【例14.3】使用lambda表达式为考试成绩分类

3.lambda表达式调用外部变量

lambda表达式除了可以调用定义好的参数,还可以调用表达式以外的变量。但是,这些外部的变量有些可以被更改,有些则不能。例如,lambda表达式无法更改局部变量的值,但是却可以更改外部类的成员变量(也可以叫作类属性)的值。

1.lambda表达式无法更改局部变量

局部变量在lambda表达式中默认被定义为final(静态)的,也就是说,lambda表达式只能调用局部变量,却不能改变其值。

【例14.4】使用lambda表达式修改局部变量

 2.lambda表达式可以更改类成员变量

类成员变量是在lambda表达式中不是被final修饰的,所以lambda表达式可以改变其值。

【例14.5】使用lambda表达式修改类成员变量

ambda表达式可以调用并修改类成员变量的值。
  ambda表达式只是描述了抽象方法是如何实现的,在抽象方法没有被调用前,lambda表达式中的代码并没有被执行,所以运行抽象方法之前类成员变量的值不会发生变化。
  要抽象方法被调用,就会执行lambda表达式中的代码,类成员变量的值就会被修改。

4.lambda表达式与异常处理

很多接口的抽象方法为了保证程序的安全性,会在定义时就抛出异常。但是lambda表达式中并没有抛出异常的语法,这是因为lambda表达式会默认抛出抽象方法原有的异常,当此方法被调用时则需要进行异常处理。

【例14.6】使用lambda表达式实现防沉迷接口

即使lambda表达式没有定义异常,原抽象方法抛出的异常仍然是存在的,当接口对象执行此方法时会被强制要求进行异常处理。

1.引用静态方法

类名::静态方法名

这个语法中出现了一个新的操作符“::”,这是由两个英文冒号组成的操作符,冒号之间没有空格。这个操作符左边表示方法所属的类名,右边是方法名。需要注意的是,这个语法中方法名是没有圆括号的。

【例14.7】使用lambda表达式引用静态方法

接口方法得出的结果正是按照add()方法中的逻辑计算出来的。

2.引用成员方法

对象名::成员方法名

与引用静态方法语法不同,这里操作符左侧的必须是一个对象名,而不是类名。这种语法也可以达到抽象方法按照类成员方法逻辑来实现的目的。

【例14.8】使用lambda表达式引用成员方法

3.引用带泛型的方法

泛型是Java开发经常使用到的功能,“::”操作符支持引用带泛型的方法。除方法外,“::”操作符也支持引用带泛型的类。

【例14.9】使用lambda表达式引用带泛型的方法

 注意
  与其他使用泛型的场景一样,要保证代码前后泛型一致,否则会发生编译错误。
  14.2.4 引用构造方法
  lambda表达式有3种引用构造方法的语法,分别是引用无参构造方法、引用有参构造方法和引用数组构造方法,下面分别进行讲解。
  1.引用无参构造方法
  引用构造方法的语法如下:

类名::new

因为构造方法与类名相同,如果操作符左右都写类名,会让操作符误以为是在引用与类名相同的静态方法,这样会导致程序出现Bug,所以引用构造方法的语法使用了new关键字。操作符右侧的写new关键字,表示引用构造方法。
  这个语法有一点要注意:new关键字之后没有圆括号,也没有参数的定义。如果类中既有无参构造方法,又有有参构造方法,使用引用构造方法语法后,究竟哪一个构造方法被引用了呢?引用哪个构造方法是由函数式接口决定的,“::”操作符会返回与抽象方法的参数结构相同的构造方法。如果找不到参数接口相同的构造方法,则会发生编译错误。

【例14.10】使用lambda表达式引用无参构造方法

 2.引用有参构造方法

引用有参构造方法的语法与引用无参构造方法一样。区别就是函数式接口的抽象方法是有参数的。

【例14.11】使用lambda表达式引用有参数的构造方法

3.引用数组构造方法

Java开发可能出现这样一种特殊场景:把数组类型当作泛型。如果方法返回值是泛型,在这种特殊场景下,方法就应该返回一个数组类型的结果。如果要求抽象方法既引用构造方法,又要返回数组类型结果,这种场景下抽象方法的参数就有了另外一个含义:数组个数。抽象方法的参数可以决定返回的数组长度,但数组中的元素并不是有值的,还需要再次赋值。引用数组构造方法的语法也会有所不同,语法如下:

类名[]::new

【例14.12】使用lambda表达式引用数组的构造方法

 5.Fuction接口

在此之前的所有实例中,想要使用lambda表达式都需要先创建或调用已有的函数式接口,但java.util.function包已经提供了很多预定义函数式接口,就是没有实现任何功能,仅用来封装lambda表达式的对象。该包中最常用的接口是Function<T,R>接口,这个接口有以下两个泛型:

  :被操作的类型,可以理解为方法参数类型。
  :操作结果类型,可以理解为方法的返回类型。

Function接口是函数式接口,所以只有一个抽象方法,但是Function接口还提供了3个已实现的方法以方便开发者对函数逻辑进行更深层的处理。

【例14.13】使用lambda表达式拼接IP地址

【例14.14】创建员工类,并按照表14.2创建初始化数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值