java-HashSet 源码分析 1
## 深入分析 Java 中的 `HashSet` 源码
`HashSet` 是 Java 集合框架中的一个重要类,它基于哈希表实现,用于存储不重复的元素。`HashSet` 允许 `null` 元素,并且不保证元素的顺序。本文将详细分析 `HashSet` 的源码,包括其数据结构、构造方法、核心操作、内部实现机制等。
### 1. `HashSet` 的基本数据结构
`HashSet` 是基于 `HashMap` 实现的,每个 `HashSet` 内部都维护了一个 `HashMap` 实例,用于存储元素。`HashSet` 的元素作为 `HashMap` 的键,所有键对应的值为一个常量对象。
`HashSet` 类的基本结构如下:
```java
public class HashSet<E> extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
static final long serialVersionUID = -5024744406713321676L;
// 底层使用的 HashMap
private transient HashMap<E, Object> map;
// HashSet 中所有键对应的值
private static final Object PRESENT = new Object();
// 默认构造方法
public HashSet() {
map = new HashMap<>();
}
// 其他构造方法和方法定义
}
```
- `map`:底层使用的 `HashMap` 实例,用于存储元素。
- `PRESENT`:`HashMap` 中所有键对应的值,这是一个常量对象。
### 2. 构造方法
`HashSet` 提供了多个构造方法,以满足不同的初始化需求。
#### 2.1 默认构造方法
```java
public HashSet() {
map = new HashMap<>();
}
```
默认构造方法使用默认初始容量(16)和加载因子(0.75)创建一个空的 `HashMap` 实例。
#### 2.2 指定初始容量和加载因子的构造方法
```java
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
```
此构造方法允许用户指定 `HashMap` 的初始容量和加载因子。
#### 2.3 指定初始容量的构造方法
```java
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
```
此构造方法允许用户指定 `HashMap` 的初始容量,加载因子使用默认值 0.75。
#### 2.4 从另一个集合创建 `HashSet`
```java
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size() / .75f) + 1, 16));
addAll(c);
}
```
此构造方法从另一个集合创建 `HashSet`,并将集合中的所有元素添加到 `HashSet` 中。
### 3. 核心操作方法
#### 3.1 添加元素
`HashSet` 提供了添加元素的方法 `add(E e)`:
```java
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
```
- `add(E e)`:将元素 `e` 添加到 `HashSet` 中。实际上是将元素 `e` 作为键,`PRESENT` 作为值存入 `HashMap` 中。如果键 `e` 已存在,则返回 `false`;否则返回 `true`。
#### 3.2 删除元素
`HashSet` 提供了删除元素的方法 `remove(Object o)`:
```java
public boolean remove(Object o) {
return map.remove(o) == PRESENT;
}
```
- `remove(Object o)`:从 `HashSet` 中删除指定的元素 `o`。如果 `HashMap` 中存在键 `o`,则删除并返回 `true`;否则返回 `false`。
#### 3.3 判断是否包含元素
`HashSet` 提供了判断是否包含某个元素的方法 `contains(Object o)`:
```java
public boolean contains(Object o) {
return map.containsKey(o);
}
```
- `contains(Object o)`:判断 `HashSet` 中是否包含指定的元素 `o`。实际上是调用 `HashMap` 的 `containsKey(Object key)` 方法。
#### 3.4 清空 `HashSet`
`HashSet` 提供了清空所有元素的方法 `clear()`:
```java
public void clear() {
map.clear();
}
```
- `clear()`:清空 `HashSet` 中的所有元素。实际上是调用 `HashMap` 的 `clear()` 方法。
### 4. 内部实现机制
#### 4.1 `HashMap` 的工作原理
为了更好地理解 `HashSet` 的实现,有必要了解 `HashMap` 的工作原理。`HashMap` 是基于哈希表的数据结构,通过散列函数将键映射到数组中的位置,从而实现快速查找、插入和删除操作。
#### 4.2 `HashMap` 的核心操作
- **计算哈希值**:`HashMap` 使用键的 `hashCode()` 方法计算哈希值,并进一步对哈希值进行处理,以减少哈希冲突。
- **处理哈希冲突**:当两个不同的键映射到同一个位置时,`HashMap` 使用链地址法(即在数组的每个位置存储一个链表)处理冲突。
- **扩容**:当 `HashMap` 的负载因子超过阈值时(默认 0.75),`HashMap` 会进行扩容,将数组大小增加一倍,并重新分配所有键值对的位置。
#### 4.3 `HashSet` 中的元素存储
在 `HashSet` 中,所有元素都作为 `HashMap` 的键存储在哈希表中。由于 `HashMap` 的键不允许重复,因此 `HashSet` 中的元素也是唯一的。
### 5. 迭代器支持
`HashSet` 实现了 `Iterable` 接口,提供了支持迭代的功能:
```java
public Iterator<E> iterator() {
return map.keySet().iterator();
}
```
- `iterator()`:返回一个迭代器,用于遍历 `HashSet` 中的元素。实际上是调用 `HashMap` 的 `keySet()` 方法返回键集合的迭代器。
相关文章:
java-HashSet 源码分析 1
## 深入分析 Java 中的 HashSet 源码 HashSet 是 Java 集合框架中的一个重要类,它基于哈希表实现,用于存储不重复的元素。HashSet 允许 null 元素,并且不保证元素的顺序。本文将详细分析 HashSet 的源码,包括其数据结构、构造方法…...
K8S 部署 EFK
安装说明 系统版本为 Centos7.9 内核版本为 6.3.5-1.el7 K8S版本为 v1.26.14 ES官网 开始安装 本次安装使用官方ECK方式部署 EFK,部署的是当前的最新版本。 在 Kubernetes 集群中部署 ECK 安装自定义资源 如果能打开这个网址的话直接用这个命令安装,打不开的话…...
AI Earth应用—— 在线使用sentinel数据VV和VH波段进行水体提取分析(昆明抚仙湖、滇池为例)
AI Earth 本文的主要目的就是对水体进行提取,这里,具体的操作步骤很简单基本上是通过,首页的数据检索,选择需要研究的区域,然后选择工具箱种的水体提取分析即可,剩下的就交给阿里云去处理,结果如下: 这是我所选取的一景影像: 详情 卫星: Sentinel-1 级别: 1 …...
基于Hadoop平台的电信客服数据的处理与分析③项目开发:搭建基于Hadoop的全分布式集群---任务9:HBase的安装和部署
任务描述 任务内容为HBase的安装部署与测试。 任务指导 HBase集群需要整个集群所有节点安装的HBase版本保持一致,并且拥有相同的配置 具体配置步骤如下: 1. 解压缩HBase的压缩包 2. 配置HBase的环境变量 3. 修改HBase的配置文件,HBase…...
go语言day09 通道 协程的死锁
Go语言学习——channel的死锁其实没那么复杂 - JackieZheng - 博客园 (cnblogs.com) 目录 通道 创建通道 1)无缓冲通道 2)有缓冲通道 通道的使用 1) 值从通道入口进 2) 值从通道出口出 信道死锁: 0)死锁现场0 1)死…...
黑马的ES课程中的不足
在我自己做项目使用ES的时候,发现了黑马没教的方法,以及一些它项目的小问题 搜索时的匹配方法 这个boolQuery().should 我的项目是通过文章的标题title和内容content来进行搜索 但是黑马它的项目只用了must 如果我们的title和content都用must&#x…...
STM32 中断编程入门
目录 一、中断系统 1、中断的原理 2、中断类型 外部中断 定时器中断 DMA中断 3、中断处理函数 中断标志位清除 中断服务程序退出 二、实际应用 中断控制LED 任务要求 代码示例 中断控制串口通信 任务要求1 代码示例 任务要求2 代码示例 总结 学习目标&…...
使用maven搭建一个SpingBoot项目
1.首先创建一个maven项目 注意选择合适的jdk版本 2.添加依赖 2.在pom.xml中至少添加依赖 spring-boot-starter-web 依赖,目的是引入Tomcat,以及SpringMVC等,使项目具有web功能。 <!-- 引入 包含tomcat,SpringMVC,…...
使用 HTTPS 已成为网站的标配了
网站使用HTTPS的原因 背景:十年前,HTTPS并不普遍,但随着网络安全意识的提高,现在已成为网站标配。 网站升级到HTTPS的动机 安全问题:HTTP缺乏安全机制,易被窃取和篡改数据。例如,电信运营商劫…...
前后端分离Nginx
背景 旧的部署方式是将前端代码打包进后端包的resource server {listen 80;listen 443 ssl;server_name xxx.test.com;location / {proxy_pass http://xxx.test.com;} }后端:https:// xxx.test.com/simcard/querySimcard 前端:https:// x…...
【简单讲解下Tauri】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...
mac上挂载linux目录
在 macOS 上挂载 CentOS 目录步骤: 在挂载前确保 macOS 和 CentOS 在同一个局域网内,并且可以相互访问。如果有网络配置问题,可能会导致挂载失败或连接被拒绝的错误。 要在 macOS 上将 CentOS 的 /disk2/go 目录通过 NFS 挂载到 /Users/zon…...
Linux系统的服务——以Centos7为例
一、Linux系统的服务简介 服务是向外部提供对应功能的进程,其运行在系统后台,能够7*24小时持续不断的提供外界随时发来的服务请求,且服务进程常驻在内存中,具有固定的端口号,通过端口号就能找到服务内容。 提供服务的一…...
Numpy矩阵运算
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl Numpy概述 Numpy是Python的一个开源数值计算扩展库,主要用于存储和处理大型多维数组和矩阵,并且提供了大量的数学函数来操作这些数组。Numpy是Pytho…...
Spring容器Bean之XML配置方式
一、首先看applicationContext.xml里的配置项bean 我们采用xml配置文件的方式对bean进行声明和管理,每一个bean标签都代表着需要被创建的对象并通过property标签可以为该类注入其他依赖对象,通过这种方式Spring容器就可以成功知道我们需要创建那些bean实…...
【Rust入门】生成随机数
文章目录 前言随机数库rand添加rand库到我们的工程生成一个随机数示例代码 总结 前言 在编程中,生成随机数是一种常见的需求,无论是用于数据分析、游戏开发还是模拟实验。Rust提供了强大的库来帮助我们生成随机数。在这篇文章中,我们将通过一…...
普通Java工程如何在代码中引用docker-compose.yml中的environment值
文章目录 一、概述二、常规做法1. 数据库配置分离2. 代码引用配置3. 编写启动类4. 支持打包成可执行包5. 支持可执行包打包成docker镜像6. docker运行 三、存在问题分析四、改进措施1. 包含environment 变量的编排文件2. 修改读取配置文件方式3. 为什么可以这样做 五、运行效果…...
微观特征轮廓尺寸测量:光学3D轮廓仪、共焦显微镜与台阶仪的应用
随着科技进步,显微测量仪器以满足日益增长的微观尺寸测量需求而不断发展进步。多种高精度测量仪器被用于微观尺寸的测量,其中包括光学3D表面轮廓仪(白光干涉仪)、共聚焦显微镜和台阶仪。有效评估材料表面的微观结构和形貌…...
Rust开发环境搭建
Rust开发环境搭建 环境 rust: 1.79.0(2024-06-13)1. Rustup下载器在线安装 windows: https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe unix: curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh2. R…...
图文识别0难度上手~基于飞浆对pdf简易ocr并转txt
前言 本篇pdf适用windows对视觉识别0基础的的纯小白用户。大佬请绕道~~ 注意: 本项目pdf的ocr对于表格、画图文字,水印等干扰没做任何处理,因此希望各位使用该功能的pdf尽量不要含有这些干扰项,以免影响翻译效果。 流程 1.构建…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
