JDK17 |java17学习 第 6 章 数据结构泛型和流行实用程序
Technical requirements
为了能够执行本章中的代码示例,您将需要以下内容:
- 装有 Microsoft Windows、Apple macOS 或 Linux 操作系统的计算机
- Java SE 版本 17 或更高版本
- 您选择的 IDE 或代码编辑器
第 1 章,Java 17 入门。包含本章代码示例的文件可在 GitHub 上的 https:// /github.com/PacktPublishing/Learn-Java-17-Programming.git 存储库,在 examples/src/main/java/com/packt/learnjava/ch07_libraries
文件夹。
Java Class Library (JCL)
JCL 是实现 语言的包的集合。简单来说,它是 .class
文件的集合,这些文件包含在 JDK 中并可以使用。一旦您安装了 Java,您就可以将它们作为安装的一部分,并可以开始使用 JCL 类作为构建块来构建您的应用程序代码,它负责许多低级管道。 JCL 的丰富性和易用性极大地促进了 Java 的流行。
要使用 JCL 包,您可以在不向 pom.xml
文件添加新依赖项的情况下导入它。 Maven 自动将 JCL 添加到类路径中。这就是标准库和外部库的区别;如果您需要在 Maven pom.xml
配置文件中添加一个库(通常是 .jar
文件)作为依赖项,这个库是一个外部库。否则,它是标准库或 JCL。
一些 JCL 包名称以 java
开头。传统上,它们被称为 核心 Java 包,而那些以 javax
> 曾经被称为 extensions。这是 完成的,因为这些扩展被认为是可选的,甚至可能独立于 JDK 发布。还有一个尝试将以前的扩展库推广为核心包。但这需要将包名称从 java
更改为 javax
,这会破坏使用 javax
包。因此,这个想法被放弃了,核心包和扩展之间的区别逐渐消失了。
这就是为什么如果您查看 Oracle 网站上的官方 Java API,您会看到不仅 java
和 javax< /code> 包,还有
jdk
, com.sun
, org.xml
,还有其他一些包。这些额外的包主要由其他专业应用程序的工具使用。在本书中,我们将主要关注主流 Java 编程,并且只讨论
java
和 javax
包。
java.lang
这个包是如此基础,以至于它 不需要被 导入供您使用。 JVM 作者决定自动导入它。它包含最常用的 JCL 类:
Object
:任何其他 Java 类的基类。Class
:在运行时携带每个加载类的元数据。String
、StringBuffer
、StringBuilder
:支持字符串
类型。- 所有原始类型的包装类:
Byte
、Boolean
、Short
、字符
,整数
,长
,浮动
和双
。 Number
:数字基本类型的包装类的基类——所有前面列出的类,除了Boolean
。System
:提供对重要系统操作和标准输入和输出的访问(我们在每个代码中都使用了System.out
对象本书中的例子)。Runtime
:提供对执行环境的访问。Thread
和Runnable
接口:创建 Java 线程的基础。Iterable
接口:由迭代语句使用。Math
:提供基本数值运算的方法。Throwable
:所有异常的基类。Error
:这是一个exception
类,因为它的所有子级都用于传达应用程序无法捕获的系统错误.Exception
:这个类和它的直接子类代表检查的异常。RuntimeException
:这个类及其子类代表未经检查的异常,也称为运行时异常。ClassLoader
:该类读取.class
文件并将其放入(加载)到内存中;它还可以用于构建自定义的类加载器。Process
和ProcessBuilder
:这些类允许 您创建其他 JVM 进程。
java.util
java.util
包的大部分内容是专用于支持 Java 集合:
Collection
接口:许多其他集合接口的基础接口,它声明了管理集合元素所需的所有基本方法;例如,size()
、add()
、remove()
、contains()
、stream()
等。它还扩展了java.lang.Iterable
接口并继承了它的方法,包括iterator()
和forEach()
,表示Collection
接口或其任何子接口的任何实现 -List
,Set
,Queue
,Deque
等——可用于迭代语句也一样,例如ArrayList
、LinkedList
、HashSet
、AbstractQueue
、ArrayDeque
等。Map
接口和实现它的类:HashMap
、TreeMap
、和别的。Collections
类:该类提供了许多用于分析、操作和转换集合的静态方法。
许多其他集合接口、类和相关实用程序也可用。
我们讨论了 Java 集合并在 章节中看到了它们的使用示例6,数据结构、泛型和流行实用程序。
java.util
包还包括其他几个有用的类:
Objects
:提供各种与对象相关的实用方法,其中一些我们在 第 6 章,数据结构、泛型和流行实用程序。Arrays
:包含 160 个静态方法来操作数组,其中一些我们在 第 6 章,数据结构、泛型和流行实用程序。Formatter
:这允许您格式化任何原始类型,包括String
、Date
等类型;我们在第 6 章中学习了如何使用它、数据结构、泛型和流行实用程序。可选
、OptionalInt
、OptionalLong
和OptionalDouble
:这些类通过包装可以为 null 或不为 null 的实际值来帮助避免NullPointerException
。Properties
:帮助读取和创建用于应用程序配置 和类似目的的键值对。Random
:通过生成伪随机数流来补充java.lang.Math.random()
方法。StringTokeneizer
:将String
对象分解为由指定分隔符分隔的标记。StringJoiner
:构造由指定分隔符分隔的 个字符序列。可选地,它被指定的前缀和后缀包围。
还有许多其他有用的实用程序类,包括支持国际化和 Base64 编码和解码的类。
java.time
java.time
包包含用于管理日期、时间、周期和持续时间的 类。 包包括以下内容:
Month
枚举。DayOfWeek
枚举。Clock
类,使用时区返回当前时刻、日期和时间。Duration
和Period
类表示和比较不同时间单位的时间量。LocalDate
、LocalTime
和LocalDateTime
类表示日期和时间,没有时区。ZonedDateTime
类表示 带有时区的日期和时间。ZoneId
类标识时区,例如 America/Chicago。java.time.format.DateTimeFormatter
类允许您按照 国际标准组织 (ISO) 格式,例如 YYYY-MM-DD 模式。- 支持日期和时间操作的其他一些类。
我们在第 6 章中讨论了这些类中的大部分、数据结构、泛型和流行实用程序。
java.io and java.nio
java.io
和 java.nio
包包含支持读写数据的类和接口 使用流、序列化和文件系统。 这两个包的区别如下:
java.io
包 类允许您在不缓存数据的情况下读取/写入数据(正如我们在 第 5 章,字符串、输入/输出和文件),而java.nio
包 的类创建允许您沿着填充的缓冲区来回移动的缓冲区。java.io
包类会阻塞流,直到所有数据都被读取或写入,而java.nio
包的类以非阻塞方式实现(我们将在 第 15 章,反应式编程)。
java.sql and javax.sql
这 两个包组成了 Java Database Connectivity (JDBC) API,它允许您 访问和处理 存储在数据源中的数据,通常是 a>关系数据库。 javax.sql
包通过提供对 包的支持来补充java.sql
包a> 以下:
DataSource
接口作为DriverManager
类的替代品- 连接和语句池
- 分布式事务
- 行集
我们将在 第 10 章中讨论这些包并查看代码示例,管理数据库中的数据。
java.net
java.net
包包含 支持应用程序 联网的类,如下所示两个级别:
我们将讨论这个包 并在 第 12 章,网络编程。
java.lang.math and java.math
java.lang.math
包包含用于执行基本数值运算的方法,例如计算 两个数值、绝对值、初等指数、对数、平方根、三角函数和许多其他数学运算。
java.math
包 补充了 java.lang< 的 Java 原始类型和包装类/code> 包,因为您可以使用
BigDecimal
和 BigInteger
类处理更大的数字。
java.awt, javax.swing, and javafx
第一个支持构建图形用户界面(GUI)的Java库对于桌面应用程序是 java.awt (AWT) 中的 Abstract Window Toolkit (AWT)代码>包。它为执行平台的本机系统提供了一个接口,允许您可以创建和管理窗口、布局和事件。它还 具有基本的 GUI 小部件(例如文本字段、按钮和菜单),提供对系统托盘的访问权限,并允许您启动 Web 浏览器并向客户端发送电子邮件从Java代码。它对本机代码的严重依赖使得基于 AWT 的 GUI 在不同平台上看起来不同。
1997 年,Sun Microsystems 和 Netscape Communications Corporation 推出了 Java 基础类,后来 称为 Swing,并将它们放在 javax.swing
包裹。使用 Swing 构建的 GUI 组件能够模拟某些本地平台的外观,但也允许您插入不依赖于平台的外观它 正在运行。它通过添加选项卡式面板、滚动窗格、表格和列表扩展了 GUI 可以拥有的小部件列表。 Swing 组件是轻量级的,因为它们不依赖于本机代码并且完全用 Java 实现。
2007 年,Sun Microsystems 宣布 创建 JavaFX,它最终成为一个用于在许多不同设备上创建和交付桌面应用程序的软件平台。它旨在取代 Swing 作为 Java SE 的标准 GUI 库。 JavaFX框架位于javafx
开头的包中,支持所有主流桌面操作系统(操作系统)和多个移动操作系统,包括 Symbian OS、Windows Mobile 和一些专有的实时操作系统操作系统。
JavaFX 基于 Cascading Style Sheets (CSS)。但是,Swing 有更多 组件和第三方库,因此使用 JavaFX 可能需要创建很久以前在 Swing 中实现的自定义组件和管道。这就是为什么,尽管 JavaFX 被推荐为桌面 GUI 实现的首选,但根据 Oracle 网站上的官方回应(http://www.oracle.com/technetwork/java/javafx/overview/faq-1446554.html#6< /a>)。因此,可以继续使用 Swing,但如果可能,最好切换到 JavaFX。
我们将在 章节中讨论 JavaFX 并查看它的代码示例12,Java GUI 编程。
External libraries
最 使用的第三方非 JCL 库的不同列表包括 20 到 100 个库。在本节中,我们将讨论大多数此类列表中包含的那些库。它们都是开源项目。
org.junit
org.junit
包是 一个开放的源码测试的根包框架的 JUnit。它可以作为以下 pom.xml
依赖项添加到项目中:
前面依赖标记中的 scope
值告诉 Maven 包含库 .jar
文件,但仅在测试代码执行时要运行,而不是在应用程序的生产 .jar
文件中。有了依赖关系,您就可以创建一个测试。您可以自己编写代码,也可以让 IDE 为您执行以下操作:
- 右击你想测试的类名。
- 选择转到。
- 选择测试。
- 点击创建新测试。
- 单击要测试的类的方法的复选框。
- 使用
@Test
注释为生成的测试方法编写代码。 - 如有必要,添加带有
@Before
和@After
注释的方法。
假设我们有以下类:
现在,您可以实现 void
multiplyByTwo()
方法,如下所示:
单元是可以测试的最小的 代码,因此得名。最佳测试实践将方法视为最小的可测试单元。这就是为什么单元测试通常会测试一个方法。
org.mockito
单元测试经常面临的问题之一是需要测试使用第三方库的方法,数据源,或另一个类的方法。在测试时,您希望控制所有输入,以便您可以预测测试代码的预期结果。这就是模拟或模拟测试代码与之交互的对象的行为的技术派上用场的地方。
开源 Mockito 框架(org.mockito
根包名)允许您这样做——创建模拟对象。使用它非常容易。这是一个简单的案例。假设我们需要测试另一个 Class1
方法:
为了测试这个方法,我们需要确保getValue()
方法返回一定的值,所以我们 将模拟此方法。为此,请按照下列步骤操作:
- 在 Maven
pom.xml
配置文件中添加依赖: - 为需要模拟的类调用
Mockito.mock()
方法: - 设置您需要从方法返回的值:
- 现在,您可以将模拟对象作为参数传递给您正在测试的调用模拟方法的方法:
- 模拟方法返回您预定义的结果:
@Test
方法 应该如下所示:
Mockito 有一定的 限制。例如,您不能模拟静态方法和私有方法。否则,这是通过可靠地预测使用的第三方类的结果来隔离您正在测试的代码的好方法。
org.apache.log4j and org.slf4j
在本书中,我们 使用了System.out
来显示结果。在实际应用程序中,您可以执行此操作并将 输出重定向到文件,例如,以供以后分析。这样做一段时间后,您会注意到您需要关于每个输出的更多详细信息:日期和时间例如,每个语句的名称,以及生成日志语句的类名。随着代码库的增长,您会发现最好将来自不同子系统或包的输出发送到不同的文件或关闭一些消息,当一切正常时,并在检测到问题时重新打开它们等等需要有关代码行为的详细信息。而且您不希望日志文件的大小不受控制地增长。
可以编写完成所有这些的代码。但是有几个框架会根据配置文件中的设置来执行此操作,您可以在每次需要更改日志记录行为时进行更改。 两个最流行的框架被称为 log4j(发音为 LOG-FOUR-JAY)和 slf4j(发音为 S-L-F-FOUR-JAY)。
这两个框架 不是竞争对手。 slf4j 框架是一个门面,提供对底层实际日志框架的统一访问;其中之一也可以是 log4j。当程序员事先不知道使用该库的应用程序将使用哪种日志框架时,这样的外观在库开发期间特别有用。通过使用 slf4j 编写代码,程序员允许您稍后对其进行配置,以便您可以使用任何日志记录系统。
因此,如果您的代码将 仅由您的团队开发的应用程序使用,那么仅使用 log4j 就足够了。否则,请考虑使用 slf4j。
与任何 第三方库一样,在使用log4j 框架之前,您必须在Maven pom.xml 中添加相应的依赖项。 xml
配置文件:
如果我们运行 前面的 main()
方法,我们 将获得以下 输出:
可以看到,如果项目中没有添加 log4j 特定的配置文件,log4j 会提供默认的配置DefaultConfiguration
类。默认配置如下:
- 日志消息将转到控制台。
- 消息的模式将是
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
。 - 日志记录的级别将是
Level.ERROR
(其他级别包括OFF
、FATAL 、
WARN
、INFO
、DEBUG
、TRACE
和ALL
)。
将 log4j2.xml
文件添加到 resources
文件夹(Maven 放置在类路径中),其中包含以下 内容:
如果这对您来说还不够好,可以更改配置,以便将不同级别的消息记录到不同的文件等等。阅读 log4j 文档以了解更多信息:https://logging.apache.org。
org.apache.commons
org.apache.commons
包是另一个流行的 库,它被开发为一个名为 的项目Apache Commons。它由一个名为 Apache Software Foundation 的开放程序员源社区维护。该组织由 Apache Group 于 1999 年成立。Apache Group 自 1993 年以来围绕着 Apache HTTP Server 的开发而发展壮大. Apache HTTP Server 是一个开源的跨平台 Web 服务器,自 1996 年 4 月以来一直是最受欢迎的 Web 服务器。
Apache Commons 项目具有以下三个组件:
- Commons Sandbox:用于 Java 组件开发的工作区;你可以为那里的开源工作做出贡献。
- Commons Dormant:当前非活动组件的存储库;您可以在那里使用代码,但您必须自己构建组件,因为这些组件可能不会很快发布。
- Commons Proper:构成实际
org.apache.commons 的可重用 Java 组件代码>库。
我们在 org.apache.commons.io 包ch07lvl1sec46">第 5 章,字符串、输入/输出和文件。
在以下小节中,我们将讨论 Commons Proper 最受欢迎的三个软件包:
org.apache.commons.lang3
org.apache.commons.collections4
org.apache.commons.codec.binary
但是,org.apache.commons
下还有更多 包,其中包含数千个类,可轻松用于制作您的代码更加优雅和高效。
lang and lang3
org.apache.commons.lang3
包是 org.apache.commons.lang
包的第 3 版。 决定创建一个新包是由于更改在版本 3 中引入的那些是向后不兼容的,这意味着 使用以前版本的 org.apache.commons.lang
包升级到版本 3 后可能会停止工作。但在大多数主流编程中,添加 3
import
语句(作为迁移到新版本的一种方式)通常不会破坏任何内容。
根据文档,org.apache.commons.lang3
包提供了高度可重用的静态实用方法,主要关注 添加java.lang
类的值。以下是 几个值得注意的例子:
ArrayUtils
类:允许您搜索和操作数组;我们在第 6 章中讨论并展示了这一点/a>,数据结构、泛型和流行实用程序。ClassUtils
类:提供一些关于类的元数据。ObjectUtils
类:检查对象数组是否为空,比较对象,并以空安全的方式计算对象数组的中值和最小值/最大值;我们在第 6 章中讨论并展示了这一点/a>,数据结构、泛型和流行实用程序。SystemUtils
类:提供有关执行环境的信息。ThreadUtils
类:查找有关当前正在运行的线程的信息。Validate
类:验证单个值和集合,比较它们,检查空值和匹配,并执行许多其他验证。RandomStringUtils
类:根据各种字符集的字符生成String
对象。StringUtils
类:我们在 第 5 章,字符串、输入/输出和文件。
collections4
虽然 org.apache.commons.collections4
包的内容看起来与 内容非常相似literal">org.apache.commons.collections
包表面上(也就是版本 3 的包), 迁移到版本 4 可能没有那么顺利就像将 4
添加到 import
语句中。版本 4 删除了不推荐使用的类,并添加了与以前版本不兼容的泛型和其他功能。
您必须很难想出此包或其子包之一中不存在的集合类型或集合实用程序。以下只是包含 的功能和实用程序的高级列表:
Bag
接口,用于具有每个对象的多个副本的集合。- 十几个实现
Bag
接口的类。例如,下面是HashBag
类的使用方法: BagUtils
类,它转换基于Bag
的集合。- 双向地图的
BidiMap
接口,它不仅允许您通过键检索值,还允许您通过值检索 键.它有几个实现,一个例子如下: MapIterator
接口提供对地图的简单快速迭代,如下所示:- 使元素保持一定顺序的有序映射和集合,就像
List
所做的那样;例如: - 垃圾收集器可以删除参考映射、它们的键和/或 值。
Comparator
接口的各种实现。Iterator
接口的各种实现。- 将数组和枚举转换为集合的类。
- 允许您测试或创建集合的并集、交集或闭包的实用程序。
CollectionUtils
、ListUtils
、MapUtils
和MultiMapUtils
类,以及 许多其他特定于接口的实用程序类。
阅读包的文档(https://commons.apache.org/proper/commons-collections) 了解更多详情。
codec.binary
org.apache.commons.codec.binary
包提供对 Base64、Base32、二进制和十六进制字符串 编码和解码的支持.这种编码是必要的,以确保您跨不同系统发送的数据不会因为不同协议中字符范围的限制而在途中发生变化。此外,一些系统将发送的数据解释为控制字符(例如调制解调器)。
下面的代码片段演示了这个包的Base64
类的基本编解码能力:
您可以在 Apache Commons 项目站点 .org/proper/commons-codec" target="_blank">https://commons.apache.org/proper/commons-codec。
Summary
在本章中,我们概述了最流行的 JCL 包的功能——即 java.lang
、java.util< /code>,
java.time
, java.io
, java.nio
, java.sql
, javax.sql
, java.net
, java.lang.math
, java.math
, java.awt
, javax.swing
和 javafx
。
最流行的外部库由 org.junit
、org.mockito
、org 表示.apache.log4j
、org.slf4j
和 org.apache.commons
包。这些可以帮助您避免在此类功能已经存在并且可以直接导入和使用的情况下编写自定义代码。
在下一章中,我们将讨论 Java 线程并演示它们的用法。我们还将解释并行处理和并发处理之间的区别。然后,我们将向您展示如何创建线程以及如何执行、监视和停止它。这不仅对那些打算为多线程处理编写代码的人有用,而且对那些想提高他们对 JVM 工作原理的理解的人也很有用,这将是下一章的主题。
Quiz
回答以下问题以测试您对本章的了解:
- 什么是 Java 类库?选择所有符合条件的:
- 已编译类的集合
- Java 安装附带的软件包
- Maven 自动添加到类路径的
.jar
文件 - 任何用 Java 编写的库
- 什么是 Java 外部库?选择所有符合条件的:
- Java 安装中未包含的
.jar
文件 - 一个
.jar
文件,必须作为依赖添加到pom.xml
中才能使用 - 非 JVM 作者编写的类
- 不属于 JCL 的类
- Java 安装中未包含的
java.lang
包中包含哪些功能?选择所有符合条件的:- 它是唯一包含 Java 语言实现的包。
- 它包含最常用的 JCL 类。
- 它包含
Object
类,它是任何 Java 类的基类。 - 它包含 Java 语言规范中列出的所有类型。
java.util
包中包含哪些功能?选择所有符合条件的:- Java 集合接口的所有实现
- Java 集合框架的所有接口
- JCL 的所有实用程序
- 类、数组、对象和属性
java.time
包中包含哪些功能?选择所有符合条件的:- 管理日期的课程。
- 它是唯一可以管理时间的包。
- 代表日期和时间的类。
- 它是唯一管理日期的包。
java.io
包中包含哪些功能?选择所有符合条件的:- 处理二进制数据流
- 处理字符流
- 处理字节流
- 处理数字流
java.sql
包中包含哪些功能?选择所有符合条件的:- 支持数据库连接池
- 支持数据库语句执行
- 提供从/向数据库读取/写入数据的能力
- 支持数据库事务
java.net
包中包含哪些功能?选择所有符合条件的:- 支持 .NET 编程
- 支持套接字通信
- 支持基于 URL 的通信
- 支持基于 RMI 的通信
java.math
包中包含哪些功能?选择所有符合条件的:- 支持最小和最大计算
- 支持大数字
- 支持对数
- 支持平方根计算
javafx
包中包含哪些功能?选择所有符合条件的:- 支持传真消息发送
- 支持传真信息接收
- 支持 GUI 编程
- 支持动画
org.junit
包中包含哪些功能?选择所有符合条件的:- 支持测试 Java 类
- 支持 Java 度量单位
- 支持单元测试
- 支持组织团结
org.mockito
包中包含哪些功能?选择所有符合条件的:- 支持 Mockito 协议
- 允许您模拟方法的行为
- 支持静态方法模拟
- 生成行为类似于第三方类的对象
org.apache.log4j
包中包含哪些功能?选择所有符合条件的:- 支持将消息写入文件
- 支持从文件中读取消息
- 支持 Java 的 log4j 协议
- 支持控制日志文件的数量和大小
org.apache.commons.lang3
包中包含哪些功能?选择所有符合条件的:- 支持 Java 语言版本 3
- 补充
java.lang
类 - 包含
ArrayUtils
、ObjectUtils
和StringUtils
类 - 包含
SystemUtils
类
org.apache.commons.collections4
包中包含哪些功能?选择所有符合条件的:- Java 集合框架接口的各种实现
- 用于 Java 集合框架实现的各种实用程序
- Vault 接口及其实现
- 包含
CollectionUtils
类
org.apache.commons.codec.binary
包中包含哪些功能?选择所有符合条件的:- 支持通过网络发送二进制数据
- 允许您对数据进行编码和解码
- 支持数据加密
- 包含
StringUtils
类