当前位置: 首页 > news >正文

Java--集合(三)之vectorlinkedlisthashset结构

文章目录

  • 0.架构图
  • 1.vector解析
  • 2.LinkedList分析
    • 2.1源码分析
    • 2.2迭代器遍历的三种方式
  • 3.set接口的使用方法
    • 3.1基本使用说明
    • 3.2基本遍历方式
    • 3.3HashSet引入
    • 3.4数组链表模拟
    • 3.5hashset扩容机制
    • 3.6hashset源码解读
    • 3.7扩容*转成红黑树机制**我的理解

0.架构图

image-20241016112117440

image-20241016112129033

1.vector解析

image-20241016193935518

和之前介绍的这个ArrayList相比,这个vector属于线程安全操作,他的这个基本的使用和我们的这个Arraylist没有太大的区别,但是这个扩容机制和我们的这个Arraylist不太一样;

在默认的情况下,我们的这个空间容量的大小就是10,然后会按照2倍扩容,这个就是和Arraylist的一个区别,因此下面的这个add,前面的10个数据是不会进行扩容的,只有后面的add(10)才会进行这个扩容的操作;

image-20241016195608833

我们可以自己去进行debug调试,这个方法就是我们的s是一个默认的参数,当我们的数据长度小于这个数据的时候根本就不会进行grow里面去进行扩容,当我们的这个循环结束的时候,已经是插入10个数据,这个时候两个是相等的,才会调用这个grow方法;

image-20241016195315284

在我们的这个grow方法里面,这个capacityIncrement小于0,对于这个三木而言,就是后面的这个oldcapacity作为结果操作,所以会进行这个二倍扩容,newcapacity就是10*2==20;

image-20241016195437914

2.LinkedList分析

linkedlist的本质上就是一个双向的链表;

2.1源码分析

我们以添加节点和删除节点为例进行源码的分析:

首先我们创建这个lineedlist的时候就是进行的初始化的工作,这个时候双向链表里面是没有节点的,因此这个时候的size=0,然后去创建第一个节点;

image-20241017132225990

添加第一个节点的时候,可以看到这个首先还是进行的这个装箱的过程,把这个基本的数据类型转换为我们的常用类integer;

image-20241017132405434

下面的这个是进行的第一次数据的插入过程:因为这个时候双向链表就是空的,所以这个时候我们的last,first都是指向的这个604地址空间位置;

image-20241017132612580

当我们插入第二个数据的时候,这个first指向的还是第一个位置的节点,但是这个last已经指向了新的节点,这个地址也是进行了更新:615;但是我们的这个l还是指向的第一个节点地址位置;

image-20241017132706647

接下来再次进行数据的插入,这个时候我们的lat再次进行更新,这个l指向的还是我们的最后一个节点的前面的一个位置的地址;

image-20241017133039785

下面的这个是进行的remove方法的调用,这个时候就是删除我们的这个链表里面的第一个节点,使用的是这个unlinkFirst方法实现的;

image-20241017133139551

这个方法里面,叫这个f的数值变为null,指向的下一个节点也是空的,这个时候这个节点就会被作为垃圾回收掉,这个时候我们的第二个数据就是头结点,因此这个first指向了原来的609地址位置;

image-20241017133221685

2.2迭代器遍历的三种方式

下面的这个就是我们的循环双向链表支持的三个遍历的方式,linkedlist.get(i)表示拿出来这个双向链表里面的第i个下标位置的节点数值;

image-20241017133250394

3.set接口的使用方法

3.1基本使用说明

set接口实现类创建的实例化对象,即这个接口对象(实现这个接口的类的对象):

1.添加元素不可以是重复的;

2.没有顺序的:添加顺序和取出来的这个顺序不是一样的;

3.可以添加空值null;

4.取出来这个顺序虽然不是添加时候的这个顺序,但是这个取出来的顺序是固定的,不会每一次都发生变化;

image-20241017171532382

set接口是collection的子接口,因此这个迭代器遍历set也是可以使用的:

3.2基本遍历方式

这个就是我们的迭代器遍历和增强for循环两个方式进行遍历;但是不支持这个普通的索引,因为这个里面是没有get方法的,没有办法根据下标进行数据的查找;

image-20241017172517319

3.3HashSet引入

我们创建这个的时候实际上这个底层走的还是我们的hashmap这个东东;

image-20241017172741245

hashset可以存放null值,但是元素不可以重复;

我们下面的算是对于这个hashset入门的一个demo案例,这个案例需要用到下面的这个类:我们在这个类里面实现了这个构造器和toString方法;

image-20241017175150505

我们创建一个hashset对象,向这个里面去插入数据,因为这个结构式不允许重复的,所以我们第二次插入的这个lucy是不会插入成功的;

但是我们的new Dog两次的这个名字是一样的,可以理解为这个堆上面开辟了不同的空间,但是两个引用指向的是相同的内容,所以两次添加这个new的dog对象是可以成功的;

接下来我们new两个同名的string对象,这个时候的第二个是不会插入成功的,为什么?需要后续学习之后方可解答~~

image-20241017175209902

3.4数组链表模拟

hashset的底层是hashmap,hashmap的底层是数组+链表+红黑树;

下面的这个就是数组链表的一个模拟情况,就是这个数组里面的每一个元素都是一个链表的头节点(我在这个上面没有完全显示);

下面的先添加这个john对象,然后添加jack对象,继续添加rose对象,每一个数组元素都是有自己的一个链表的,这个就是我们后面分析源码可能会用到的数组链表结构;

image-20241017180937256

首先需要定义一个node的类,这个里面成员就是我们的结点的数值和下一个节点内容;

image-20241017182345208

然后就是创建对象的过程,我们把这个john放到这个里面的2下标的位置,然后剩下的添加的元素都和这个john组成链表,这个只是为了说明问题,实际上添加的时候是进行这个这个hash的索引分配;

image-20241017181349294

运行结束之后,我们就可以看到这个2位置对应的已经形成了一个链表,这个链表里面已经有了我们插入的三个元素;

image-20241017181510774

3.5hashset扩容机制

1.首先hash值,这个就是一个数字;

2.通过对于这个哈希值的运算,得到一个下标,这个下标就是我们要添加这个数组元素的链表位置,例如我们运算之后得到的是3,就会在这个数组3下标的链表上进行元素的添加;

3.如果这个位置上面没有其他的元素,就会直接放到这个位置上面去,如果有元素,使用这个equals进行判断,这个equals并不是简单的比较两个数据的内容,因为这个方法我们是可以进行重写的;

4.比较这个equals之后,如果相等,就不会进行添加,否则就会尾插到这个链表的后面;

image-20241017182144632

3.6hashset源码解读

table就是一个属性,刚开始这个table就是null,这个时候会进入这个resize方法里面去,这个就是进行的扩容的操作;

image-20241017203743596

我们扩容的这个大小就是16,但是这个16是我们的数组的大小,每一个数组元素对应的这个链表多少个节点现在是不确定的(后面会说到,默认是8个大小);

image-20241017203820652

这个时候我们发现这个对象已经插入到了这个13位置,我们上面的是我们自己设置的插入到2下标的位置,这个是自己通过计算匹配之后插入到的这个13位置的;

image-20241017203944305

例如我们想要进行这个数据的插入,匹配到了这个2下标的位置,这个时候通过和这个johu,jack,rose一个一个的进行比对,如果出现了这个equals一样的情况,这个就会进行break操作,否则就会把这个数据添加到我们的这个链表的3位置,这个就是添加的过程;

image-20241017204728999

3.7扩容*转成红黑树机制**我的理解

1.上面介绍到了这个默认开辟的数组大小是16,实际上这个12就是临界(0.75倍的关系,0.75叫做加载因子),就是当我们的这个数组里面的12个位置都被占用的时候,我们就会考虑扩容,因为害怕剩下的4个大小不够使用,这个是第一点;

2.接下来就会进行2倍扩容,例如从16扩到32,这个时候的临界还是0.75倍,即32*0.75=24,也就是说这个达到24之后又会考虑进行扩容操作;

3.链表达到8个之后,这个就会考虑进行树化操作,即把这个数组链表转换为这个红黑树的结构,但是这个前提条件是我们的这个数组已经大于64,因为可能是因为这个数组不够长,我们首先会对于这个数组进行扩容;

4.如果这个数组元素足够多,数组足够长,而且这个链表的节点已经大于8个,这个时候才会进行这个红黑树的转换(通过调用这个红黑树的相关的算法);

5.这个链表也不是达到8一定会树化,这个8不是确定的,可能是大于8才会树化,可能是9,可能是10,这个8是一个默认值,不是确定数值;

6.底层源码里面的这个size++并不仅仅是我们的数组元素增加的时候才会size++,我们的这个数组元素对应的这个链表上面的这个node节点增加的时候我,我们也会进行这个size++的操作;

7.上面说的这个第六点主要是为了说明什么问题?就是我们的这个这个最开始数组不是16个大小吗,就是达到12的时候就会触发扩容,但是这个12并不是12个数组元素,可能会是说这个数组只有两个元素,但是这个链表上面有10个节点,这个时候就是size=12,我们接下来插入数据(无论是节点还是数组元素),都会触发扩容操作,也就是说,即使我们的数组大量是空的,但是我们的这个链表上面的节点足够多,这个也是会出触发我们的这个数组的扩容;

8.首先,我们进行这个数据的添加的时候首先会比较这个hash值,如果哈希值不一样,说明这个下标索引就不一样,这个时候肯定会放进去,这个时候不会进行这个equals操作,当我们的这个hash值一样的时候,说明我们会插入到一个链表上面去,这个时候才会调用这个equals方法;

9.new对象的时候,hash值很难是一样的,但是我们可以重写这个hasncode方法,让他们的属性相同的时候,就会拥有一样的hash值;

如果哈希值不一样,说明这个下标索引就不一样,这个时候肯定会放进去,这个时候不会进行这个equals操作,当我们的这个hash值一样的时候,说明我们会插入到一个链表上面去,这个时候才会调用这个equals方法;

9.new对象的时候,hash值很难是一样的,但是我们可以重写这个hasncode方法,让他们的属性相同的时候,就会拥有一样的hash值;

相关文章:

Java--集合(三)之vectorlinkedlisthashset结构

文章目录 0.架构图1.vector解析2.LinkedList分析2.1源码分析2.2迭代器遍历的三种方式 3.set接口的使用方法3.1基本使用说明3.2基本遍历方式3.3HashSet引入3.4数组链表模拟3.5hashset扩容机制3.6hashset源码解读3.7扩容*转成红黑树机制**我的理解 0.架构图 1.vector解析 和之前介…...

upload-labs Pass-04

upload-labs Pass-04 在进行测试前,先了解一下.htaccess文件 .htaccess文件 .htaccess是Apache网络服务器一个配置文件,当.htaccess文件被放置在一个通过Apache Web服务器加载的目录中,.htaccess文件会被Apache Web服务器软件检测并执行&…...

如何修改jupyter notebook的工作目录

1.生成配置文件: 打开Anaconda Prompt,输入如下命令 jupyter notebook --generate-config 用代码可以找到配置文件位置,如果没有填y可以生成。 2.修改配置文件: 修改jupyter_notebook_config.py的配置文件,需将c.Not…...

23种设计模式具体实现方法

提示:文章 文章目录 前言一、背景二、设计模式1、代理模式2、适配器模式2.1 总结 三、3.1 总结 前言 前期疑问: 本文目标: 一、背景 最近 二、设计模式 1、代理模式 参考的这篇文章,代理模式(Proxy) 同时这篇文章还引用了另…...

cisco网络安全技术第3章测试及考试

测试 使用本地数据库保护设备访问(通过使用 AAA 中央服务器来解决)有什么缺点? 试题 1选择一项: 必须在每个设备上本地配置用户帐户,是一种不可扩展的身份验证解决方案。 请参见图示。AAA 状态消息的哪一部分可帮助…...

数据结构练习题5(链表和栈)

1环形链表 II 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测…...

计算机网络408真题解析(湖科大教书匠)

09年...

uniapp+vue3+uview-plus修改默认样式

最近使用uniappvue3uview-plus开发微信小程序中,使用uview-plus自定义底部导航栏tabbar时,遇到修改默认样式不生效问题 使用传统的 ::v-deep、:deep、::v-deep,或者style标签中去掉scoped也是无效的,有好的方案欢迎交流&#xff…...

数控机械制造工厂ERP适用范围有哪些

在当今制造业高速发展的背景下,企业资源计划(ERP)系统已成为提升工厂管理效率、实现生产自动化与信息化的关键工具。特别是对于数控机械制造工厂而言,一个合适的ERP系统能够帮助其优化生产流程、提高产品质量、降低生产成本并增强市场竞争力。 1. 生产计…...

华为配置 之 Console线路配置

目录 简介: 知识点: 配置Console线路密码 1.密码认证模式 2.AAA认证模式 知识点: 总结: 简介: 使用PC模拟器与路由器相连(与交换机相连原理一样),在关机状态下,使用…...

小米等手机彻底关闭快应用

文章目录 快应用的是非最终措施:撤销快应用隐私协议配套措施:安卓去除开屏广告 无用的操作:载快应用小米手机无用,其他手机可以尝试的操作关闭唤起快应用服务打开防止误触、后台启动其他应用 其他措施:冻结、加密快应用…...

【每日一题】24.10.14 - 24.10.20

10.14 直角三角形1. 题目2. 解题思路3. 代码实现(AC_Code) 10.15 回文判定1. 题目2. 解题思路3. 代码实现(AC_Code) 10.16 二次方程1. 题目2. 解题思路3. 代码实现(AC_Code) 10.17 互质1. 题目2. 解题思路3…...

CMake与Qt4/Qt5的结合使用指南

CMake与Qt4/Qt5的结合使用指南 一、同时使用Qt 4和Qt 5二、Qt构建工具2.1 AUTOMOC2.2 AUTOUIC2.3 AUTORCC 三、<ORIGIN>_autogen目标四、Visual Studio生成器五、Windows上的qtmain.lib六、其他文章推荐 在CMake中&#xff0c;您可以方便地找到并使用Qt 4和Qt 5库。Qt 4库…...

TwinCAT3添加PLC轴,并建立PLC轴与NC轴的链接

右键PLC选项&#xff0c;点击创建新项 在弹出的对话框中&#xff0c;选择PLC Templates&#xff0c;然后选择Standard PLC Project&#xff0c;填写项目名称后点击添加 在PLC项目目录中右键GVLs&#xff0c;选择Add&#xff0c;添加Global Variable List&#xff08;全局变…...

Linux操作系统如何制作U盘启动盘

在麒麟系统中有一款U盘启动器软件&#xff0c;它是用于制作系统启动U盘的工具&#xff0c;方便无光驱的电脑安装操作系统&#xff0c;也可以反复使用一个U盘&#xff0c;避免光盘的浪费。下面对该U盘启动器使用方法做详细讲解。 1.准备需要安装的系统镜像文件。 图 1 2.准备1…...

如何防止SpringBoot中的jar反编译?解决相关报错及踩到的坑

目录 1. 面对的场景 2. 方案 2.1 使用代码混淆 2.2 JAR包加密 3. 项目操作 4. 启动方式 5. 踩到的各种坑 5.1 java -jar xxx-0.0.1-SNAPSHOT.jar 没有主清单属性 5.2 Caused by: java.lang.IllegalArgumentException: Unrecognized option: -pwdfxw-jar 1. 面对的场景…...

Axios 基本使用

Axios 是一个异步请求技术,核心作用就是用来在页面中发送异步请求,并获取对应数据在页面中渲染 页面局部更新技术 Ajax 中文网站:https://www.kancloud.cn/yunye/axios/234845 安装: <script src"https://unpkg.com/axios/dist/axios.min.js"></script&g…...

前端大佬都在用的actionDelegationMiddleware究竟有多香?

作为一个前端开发者,我深知跨组件通信的痛点。今天,我要和大家分享一个让我眼前一亮的工具 - alovajs 的 actionDelegationMiddleware。这个中间件简直就是跨组件通信的得力助手!它让我们可以在任意组件中触发其他组件的请求操作,解决了很多麻烦。用了它之后,我感觉整个项目的架…...

解决k8s集群中安装ks3.4.1开启日志失败问题

问题 安装kubesphere v3.4.1时&#xff0c;开启了日志功能&#xff0c;部署时有三个pod报错了 Failed to pull image “busybox:latest”: rpc error: code Unknown desc failed to pull and unpack image “docker.io/library/busybox:latest”: failed to copy: httpRead…...

Qml-Item的Id生效范围

Qml-Item的Id生效范围 前置声明 本实例在Qt6.5版本中做的验证同一个qml文件中&#xff0c;id是唯一的&#xff0c;即不同有两个相同id 的Item;当前qml文件中声明的id在当前文件中有效&#xff08;即如果其它组件中传入的id&#xff0c;与当前qml文件中id 相同&#xff0c;当前…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...