Java 核心技术卷 I 学习记录八

news2024/11/19 15:33:14

Java 核心技术卷 I 学习记录八

  • 六、接口、lambda表达式与内部类
    • 3、lambada表达式
      • 1、为什么引入lambda表达式
      • 2、lambda表达式的语法
      • 3、函数式接口
      • 4、方法引用
      • 5、构造器引用
      • 6、变量作用域
      • 7、处理lambda表达式
      • 8、再谈Comparator

六、接口、lambda表达式与内部类

3、lambada表达式

使用 lambda 表达式采用一种简洁的语法定义代码块。

1、为什么引入lambda表达式

lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。

2、lambda表达式的语法

// 检查一个字符串是否比另一个字符串短
first.length() -second.length();

// Java是一种强类型语言,指定变量类型
(String first, String second) -> first.length() -second.length();

lambda表达式就是一个代码块,以及必须传入代码的变量规范。
Java中的一种lambda表达式形式:参数,箭头(->)以及一个表达式。如果代码要完成的计算无法放在一个表达式中,就可以像写方法一样,把这些代码放在 {} 中,并包含显式的return语句。

// lambda例子:检查一个字符串是否比另一个字符串短
(String first, String second) -> {
	if (first.length() < second.length()) return -1;
	else if (first.length() > second.lenght()) return 1;
	else return 0;
}

即使lambda表达式没有参数,仍然要提供空括号,就像无参数方法一样:

() -> { 
	for (int i=100;i>=0;i-- ) System.out.println(i); 
}

如果可以推导出一个lambda表达式的参数类型,就可以忽略类型:

Comparator<String> comp
	= (first, second) // Same as (String first, String second) 
		-> first.length() - second.length();

在这里,编译器可以推导出first和second必然是字符串,因为这个lambda表达式将赋给一个字符串比较器。
如果方法只有一个参数,而且这个参数的类型可以推导出来,甚至还可以省略小括号:

ActionListener listener = event ->
	System.out.println("The time is " + new Date()); // Instead of (event) -> . . . or (ActionEvent event) -> . . .

无需指定lambda表达式的返回类型。lambda表达式的返回类型会根据上下文推导出。

3、函数式接口

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口(functional interface)。
在Java中,对lambda表达式所能做的也只是能转换为函数式接口。在其他支持函数字面量的程序设计语言中,可以声明函数类型(如(String, String) -> int)、声明这些类型的变量,还可以使用变量保存函数表达式。不过,Java设计者还是决定保持我们熟悉的接口概念,没有为Java语言增加函数类型。

4、方法引用

如果已经有现成的方法已经可以完成你想要传递到其他代码的某个动作。

// 假如希望只要出现一个定时器事件就打印这个事件对象
Timer t = new Timer(1000, event -> System.out.println(event));

// 如果直接把println方法传递到Timer构造器
Timer t = new Timer(1000, System.out::println);

表达式System.out::println是一个方法引用(method reference),它等价于lambda表达式x -> System.out.println(x);。
要用::操作符分隔方法名与对象或类名。主要有3种情况:

  • object::instanceMethod
  • Class::staticMethod
  • Class::instanceMethod

在前2种情况中,方法引用等价于提供方法参数的lambda表达式。对于第3种情况,第1个参数会成为方法的目标。
可以在方法引用中使用this参数。例如,this::equals等同于x -> this.equals(x)。使用super也是合法的。super::instanceMethod,使用this作为目标,会调用给定方法的超类版本。

5、构造器引用

构造器引用与方法引用很类似,只不过方法名为new。例如,Person::new是Person构造器的一个引用。具体引用哪一个构造器取决于上下文。
可以用数组类型建立构造器引用。例如,int[]::new是一个构造器引用,它有一个参数:即数组的长度。这等价于lambda表达式 x -> new int[x]。
Java有一个限制,无法构造泛型类型T的数组。数组构造器引用对于克服这个限制很有用。表达式new T[n]会产生错误,因为这会改为new Object[n]。对于开发类库的人来说,这是一个问题。

6、变量作用域

可能希望能够在lambda表达式中访问外围方法或类中的变量。
lambda表达式有3个部分:

  • 1、一个代码块;
  • 2、参数;
  • 3、自由变量的值,这是指非参数而且不在代码中定义的变量。

关于代码块以及自由变量值有一个术语:闭包(closure)。如果有人吹嘘他们的语言有闭包,现在你也可以自信地说Java也有闭包。在Java中,lambda表达式就是闭包。

7、处理lambda表达式

使用lambda表达式的重点是延迟执行(deferred execution)毕竟,如果想耍立即执行代码,完全可以直接执行,而无需把它包装在一个lambda表达式中。之所以希望以后再执行代码,这有很多原因,如:

  • 在一个单独的线程中运行代码;
  • 多次运行代码;
  • 在算法的适当位置运行代码(例如,排序中的比较操作);
  • 发生某种情况时执行代码(如,点击了一个按钮,数据到达,等等);
  • 只在必要时才运行代码。

Java API中提供的最重要的函数式接口。

函数式接口参数类型返回类型抽象方法名描述其他方法
Runnablevoidrun作为无参数或返回值的动作运行
SupplierTget提供一个T类型的值
ConsumerTvoidaccept处理一个T类型的值addThen
BiConsumer<T, U>T, Uvoidaccept处理T和U类型的值addThen
Function<T, R>TRapply有一个T类型参数的函数compose, addThen, indetify
BiFunction<T, U, R>T, URapply有T和U类型参数的函数addThen
UnaryOperatorTTapply类型T上的一元操作符compose, addThen, identify
BinaryOperatorT, TTapply类型T上的二元操作符andThen, maxBy, minBy
PredicateTbooleantest布尔值函数and, or, negate, isEqual
BiPredicate<T, U>T, Ubooleantest有两个参数的布尔值函数and, or, negate

基本类型int、long和double的34个可能的规范。最好使用这些特殊化规范来减少自动装箱。

函数式接口参数类型返回类型抽象方法名
BooleanSuppliernonebooleangetAsBoolean
PSuppliernonepgetAsP
PConsumerpvoidaccept
ObjPConsumerT, pvoidaccept
PFunctionpTapply
PToQFunctionpqapplyAsQ
ToPFunctionTpapplyAsP
ToPBiFunction<T, U>T, UpapplyAsP
PUnaryOperatorppapplyAsP
PBinaryOperatorp, ppapplyAsP
PPredicatepbooleantest

8、再谈Comparator

Comparator接口包含很多方便的静态方法来创建比较器。这些方法可以用于lambda表达式或方法引用。
静态comparing方法取一个“键提取器”函数,它将类型T映射为一个可比较的类型(如 String)。对要比较的对象应用这个函数,然后对返回的键完成比较。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2243468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Restful API接⼝简介及为什么要进⾏接⼝压测

一、RESTful API简介 在现代Web开发中&#xff0c;RESTful API已经成为一种标准的设计模式&#xff0c;用于构建和交互网络应用程序。本文将详细介绍RESTful API的基本概念、特点以及如何使用它来设计高效的API接口。 1. 基于协议 HTTP 或 HTTPS RESTful API通常使用HTTP&am…

R语言统计分析与MATLAB数学建模书籍推荐

文章目录 一、《R语言统计分析与可视化》1.1 内容核心1.2 内容简介 二、《MATLAB数学建模从入门到精通》2.1 关键点2.2 内容简介2.3 作者简介 一、《R语言统计分析与可视化》 R语言统计分析与可视化从入门到精通。学R语言、练语法、取数据、预处理、可视化、回归分析、方差分析…

智慧社区平台系统提升物业管理效率与居民生活质量

内容概要 智慧社区平台系统是为应对现代城市管理挑战而诞生的重要工具。随着城市化进程的加快&#xff0c;传统的物业管理方式已经难以满足日益增长的居民需求和管理复杂性。因此&#xff0c;引入智能化管理手段显得尤为重要。这个系统不仅仅是一个简单的软件&#xff0c;它是…

【ASR技术】WhisperX安装使用

介绍 WhisperX 是一个开源的自动语音识别&#xff08;ASR&#xff09;项目&#xff0c;由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型&#xff0c;通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别&#xff08;large-v2 为 70 倍实时&#xf…

STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组

STM32CUBEIDE FreeRTOS操作教程&#xff08;九&#xff09;&#xff1a;eventgroup事件标志组 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为…

力扣(leetcode)题目总结——动态规划篇

leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏&#xff1a;点击进入 leetcode题目分类 关注走一波 前言&#xff1a;本系列文章初衷是为了按类别整理出力扣&#xff08;leetcode&#xff09;最经典题目&#xff0c…

计算器的实现

计算器的实现 计算器实现思路 我们⽇常写的计算表达式都是中缀表达式&#xff0c;也就是运算符在中间&#xff0c;运算数在两边&#xff0c;但是直接读取⽆ 法⻢上进⾏运算因为⼀个计算表达式还涉及运算符优先级问题。如&#xff1a; 都⽆法运算&#xff0c;因为后⾯还有括号优…

Python蓝桥杯刷题1

1.确定字符串是否包含唯一字符 题解&#xff1a;调用count函数计算每一个字符出现的次数&#xff0c;如果不等于1就输出no&#xff0c;并且结束循环&#xff0c;如果等于1就一直循环直到计算到最后一个字符&#xff0c;若最后一个字符也满足条件&#xff0c;则输出yes import…

《基于 PySpark 的电影推荐系统分析及问题解决》

以下是一篇关于上述代码的博客文章&#xff1a; 基于PySpark的电影推荐系统实现与分析 在当今数字化时代&#xff0c;个性化推荐系统在各个领域中都发挥着至关重要的作用&#xff0c;尤其是在娱乐行业&#xff0c;如电影推荐。本文将详细介绍如何使用PySpark构建一个简单的电…

每天五分钟深度学习pytorch:批归一化全连接网络完成手写字体识别

本文重点 前面我们学习了普通的全连接神经网络,后面我们学习了带有激活层的全连接神经网络,本文我们继续进一步升级,我们学习带有批归一化的全连接神经网络,批归一化可以加快神经网络的训练速度,减少过拟合,具体它的原理,大家可以看我们的《每天五分钟深度学习》专栏,…

JavaWeb后端开发知识储备1

目录 1.DTO/VO/PO 2.MVC架构/微服务架构 3.JWT令牌流程 4.ThreadLocal 5.接口路径/路径参数 6.自定义注解 1.DTO/VO/PO 1.1 DTO DTO 即 Data Transfer Object—— 数据传输对象&#xff0c;是用于传输数据的对象&#xff0c;通常在服务层与表现层之间传递数据&#xff…

什么是SMARC?模块电脑(核心板)规范标准简介三

1. 概念 SMARC&#xff08;Smart Mobility ARChitecture&#xff0c;智能移动架构&#xff09;是一种通用的小型计算机模块定义&#xff0c;基于ARM和X86技术的模块化计算机低功耗嵌入式架构平台&#xff0c;旨在满足低功耗、低成本和高性能的应用需求。这些模块通常使用与平板…

Filebeat升级秘籍:解锁日志收集新境界

文章目录 一、什么是filebeat二、Filebeat的工作原理2.1 filebeat的构成2.1.1 Prospector 组件2.1.2 Harvester 组件 2.2 filebeat如何保存文件的状态2.3 filebeat何如保证至少一次数据消费 三、Filebeat配置文件四、filebeat对比fluented五、Filebeat的部署安装5.1裸金属安装5…

C++小白实习日记——Day 4 将本地项目上传到gitee

生活就像一坨狗屎 我跑的代码老板说耗时太长了&#xff0c;不知道要怎么做才能耗时小一点 老板把我加到企业gitee里了&#xff0c;让我将代码上传到个人仓库&#xff1a; 新建一个文件夹当做库文件&#xff0c;点git bash here——> git init——>git config --global…

qiankun主应用(vue2+element-ui)子应用(vue3+element-plus)不同版本element框架css样式相互影响的问题

背景&#xff1a;qiankun微前端架构实现多应用集成 主应用框架&#xff1a;vue2 & element-ui 子应用框架&#xff1a;vue3 & element-plus >> 问题现象和分析 登录页面是主应用的&#xff0c;在登录之后才能打开子应用的菜单页面&#xff0c;即加载子应用。 首…

云渲染,解决houdini特效缓存太大上传太慢的问题

对于从事 Houdini 创作的艺术家和设计师们来说&#xff0c;使用云渲染的朋友&#xff0c;缓存太大导致云渲染上传慢一直是一个令人头疼的问题。然而&#xff0c;现在有了成都渲染 101 云渲染&#xff0c;这个难题迎刃而解。Houdini 以其强大的功能能够创建极为复杂和逼真的特效…

前端开发迈向全栈之路:规划与技能

一、前端开发与全栈开发的差异 前端开发主要负责构建和实现网页、Web 应用程序和移动应用的用户界面。其工作重点在于网页设计和布局&#xff0c;使用 HTML 和 CSS 技术定义页面的结构、样式和布局&#xff0c;同时运用前端框架和库如 React、Angular 或 Vue.js 等构建交互式和…

学习QT第二天

QT6示例运行 运行一个Widgets程序运行一个QT Quick示例 工作太忙了&#xff0c;难得抽空学点东西。-_-||| 博客中有错误的地方&#xff0c;请各位道友及时指正&#xff0c;感谢&#xff01; 运行一个Widgets程序 在QT Creator的欢迎界面中&#xff0c;点击左侧的示例&#xf…

删除课表中课程

文章目录 概要整体架构流程技术细节小结 概要 业务分析 删除课表中的课程有两种场景&#xff1a; 用户直接删除已失效的课程 用户退款后触发课表自动删除 技术细节 退款通知 其中用户退款与用户报名课程类似&#xff0c;都是基于MQ通知的方式。具体代码是在tj-trade模块的…