| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Java核心技术1-lambda表达式 -> 正文阅读 |
|
[Java知识库]Java核心技术1-lambda表达式 |
本文是《Java核心技术1》第10版 Chap6 中关于【lambda 表达式】的要点总结。 在文章 Java核心技术1-接口 中,我们了解了接口。 本文我们介绍 lambda 表达式,这是一种表示可以在将来某个时间点执行的代码块的简洁方法。使用 lambda 表达式,可以用一种精巧而简洁的方式表示使用回调或变量行为的代码。 为什么引入 lambda 表达式我们经常有这样的需求:将一个代码块传递到某个对象,这个代码块会在将来某个时间调用。 例如:要定制比较器完成排序,可以向 sort 方法传入一个 Comparator 对象。
在数组完成排序之前,sort 方法会一直调用 compare 方法,只要元素的顺序不正确就会重新排列元素。如果能将比较元素所需的代码段放在 sort 方法中,这个代码将与其余的排序逻辑集成。 上面的做法是构造一个对象,这个对象的类需要有一个方法能包含所需的代码。 而 lambda 表达式是一个可传递的代码块,可以在以后执行一次或多次。 lambda 表达式的写法常规形式:
完成的计算无法放在一个表达式中,则需要放在 {} 里并显式给出 return。
没有参数的情况,也要保留括号。
参数类型可以推导的情况,可以忽略其类型。
如果方法只有一个参数,而且这个参数的类型可以推导得出,那么还可以省略小括号。
无需指定 lambda 表达式的返回类型。lambda 表达式的返回类型总是会由上下文推导得出。例如 如果一个 lambda 表达式只在某些分支返回一个值,而在另外一些分支不返回值,例如 例子: 在比较器中用 lambda 表达式
函数式接口Java 中有很多封装代码块的接口,例如 Comparator 就是一个。lambda 表达式与这些接口是兼容的。 对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个 lambda 表达式。这种接口称为函数式接口(functional interface)。
例如 Arrays.sort 的第二个参数需要一个 Comparator 实例,而 Comparator 就是只有一个方法的接口,因此可以提供 lambda 表达式 :
Arrays.sort 会接收实现了
在 Java 对 lambda 表达式能做的操作只有转换为函数式接口,lambda 表达式也不能赋给 Object 类型的变量,因为 Object 不是一个函数式接口。 **java.util.function 中定义了很多通用的函数式接口。例如:
但注意,comp 对于排序是没有帮助的,因为 Arrays.sort 不接收 BiFunction。Java 中类似于 Comparator 的接口往往有一个特定的用途,而不只是提供一个有指定参数和返回类型的方法。 java.util.function 中有一个 Predicate 接口:
ArrayList 类有一个 removeIf 方法,它的参数就是一个 Predicate,这个接口专门用来传递 lambda 表达式。例如:
上面的代码将从一个数组列表中删除所有 null 值。 方法引用表达式 System.out::println 就是一个方法引用,它等价于 lambda 表达式 假设要对字符串排序,不考虑字母大小写,用方法引用可以写成下面这样:
在前 2 种情况中,方法引用等价于提供方法参数的 lambda 表达式。例如:
第 3 种情况,第 1 个参数会成为方法的目标,例如:
如果有多个同名的重载方法,编译器就会尝试从上下文中找出你指的那一个方法。例如,Math.max 方法有两个版本,一个用于整数,另一个用于double 值。选择哪一个版本取决于 Math::max 转换为哪个函数式接口的方法参数。 类似于 lambda 表达式,方法引用不能独立存在,总是会转换为函数式接口的实例。 在方法引用中还可以使用 this 参数,例如:
方法引用也可以使用 super,此时用 this 作为目标,会调用给定方法的超类版本,例如:
构造器引用构造器引用与方法引用类似,只不过方法名为 new。例如: Person::new 是 Person 构造器的一个引用,具体哪一个构造器取决于上下文。
以上代码中 stream、map、collect 等方法是单独的话题,以后再来学习。现在的重点是 map 方法会为各个列表元素调用 Person(String) 构造器。 可以用数组类型建立构造器引用,例如 Java 有一个限制:无法构造泛型类型 T 的数组, 假设我们需要一个 Person 对象数组,Stream 接口有一个 toArray 可以返回 Object 数组:
如果想要得到 Person 引用数组,而不是 Object 引用数组,这个问题在流库中通过构造器引用解决:把
toArray 方法调用这个构造器来得到一个正确类型的数组。然后填充这个数组并返回。 lambda 表达式的变量作用域一个 lambda 表达式有 3 个部分:
其中:
在 lambda 表达式中要访问外围方法或类中的变量,注意以下几点:
处理 lambda 表达式使用 lambda 表达式的重点是延迟执行(deferred execution)。因为如果想要立即执行代码,完全可以直接执行,而无需把它包装在一个 lambda 表达式中。 希望延迟执行,主要有以下几个原因:
例子: 重复一个动作 n 次我们定义一个 repeat 函数,有两个参数,一个表示次数,另一个表示动作。一个示例调用如下:
第二个参数要接受 lambda 表达式,需要选择(或者自己提供)一个函数式接口。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZcvfNa90-1654179190860)(https://chengzhaoxi.oss-cn-beijing.aliyuncs.com/blog/Java核心技术1-lambda表达式/1.png)] 上面是 Java 中最重要的函数式接口,这里我们可以用 Runnable 接口:
在调用 action.run() 的时候,会执行 lambda 表达式的主体。 在前面的重复动作中,如果我们还想知道动作出现在哪一次迭代中,就要相应地换一个合适的函数式接口:其中包含一个方法,有一个整数参数且返回类型为 void。 处理int值的标准接口如下:
下面是基本类型 int、long 和 double 的 34 个可能的规范。最好使用这些特殊化规范来减少自动装箱,例如前面的代码中使用了 IntConsumer 而不是 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0bOWvh0a-1654179190862)(https://chengzhaoxi.oss-cn-beijing.aliyuncs.com/blog/Java核心技术1-lambda表达式/2.png)] 大多数标准函数式接口都提供了非抽象方法来生成或合并函数。例如,
如果设计你自己的接口,其中只有一个抽象方法,可以用 Comparator 拾遗Comparator 接口包含很多方便的静态方法来创建比较器。这些方法可以用于 lambda 表达式或方法引用。 例如静态 comparing 方法:取一个“键提取器”函数,它将类型 T 映射为一个可比较的类型(如String)。对要比较的对象应用这个函数,然后对返回的键完成比较。 例如,假设有一个 Person 对象数组,可以如下按名字对这些对象排序:
可以把比较器与 thenComparing 方法串起来:
可以为 comparing 和 thenComparing 方法提取的键指定一个比较器。例如,可以如下根据人名长度完成排序:
**comparing 和 thenComparing 方法都有变体形式,可以避免 int、long 或 double 值的装箱。**例如:
如果键函数可以返回 null,则要用 nullsFirst 和 nullsLast 适配器。 naturalOrder 方法可以为任何实现了 Comparable 的类建立一个比较器。 静态 reverseOrder 方法会提供自然顺序的逆序。要让比较器逆序比较,也可以用 reversed 实例方法,例如:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 20:54:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |