java集合总结
1.常见集合
- Collection
- List:有序可重复集合,可直接根据元素的索引来访问
- Vector-Stack
- ArrayList
- LinkedList
- Queue:队列集合
- Deque-LinkedList、ArrayDeque
- PriorityQueue
- Set:无序不可重复集合,只能根据元素本身来访问
- Hashset-LinkedHashSet
- SortedSet-TreeSet
- EnumSet
- List:有序可重复集合,可直接根据元素的索引来访问
- Map:存储key-value对的集合,可根据元素的key来访问value
- IdentityHashmap
- WeakHashMap
- HashMap-LinkedHashMap
- HashTable-Properties
- SortedMap-TreeMap
- EnumMap
2.线程安全和线程不安全
- 线程安全:Hashtable、ConcurrentHashMap、Vector(synchronized)、Stack
- 线程不安全:HashMap、ArrayList、LinkedList、HashSet、TreeSet、TreeMap
3.ArrayList与LinkedList
- 线程安全:不安全
- 底层数据结构
- ArrayList:Object数组
- LinkedList:双向循环链表
- 插入删除是否受位置影响
- ArrayList:数组存储,插入和删除元素的时间复杂度受元素位置影响,
- LinkedList:链表存储,插入和删除元素时间复杂度不受位置影响
- 是否支持快速随机访问
- ArrayList:实现了RandomAccess接口,能随机访问
- LinkedList:不支持高效的随机元素访问
- 内存空间占用
- ArrayList:在list列表的结尾会预留一定的容量空间
- LinkedList:每个元素都需要消耗比ArrayList更多的空间(要存放直接后继和直接前驱和数据)
4.ArrayList扩容机制
本质:计算出新的扩容数组size后实例化,并将原有数组内容复制到新数组去,默认情况下,新的容量会是原容量的1.5倍
5.Array和ArrayList
- Array可以包含基本类型和对象类型,ArrayList只能包含对象类型
- Array大小是固定的,ArrayList的大小是动态变化的
- ArrayList提供了更多的方法和特性,eg:addAll(),removeAll(),iterator()等
6.HashMap
- 底层数据结构
- 1.7 数组+链表,链表主要解决哈希冲突
- 1.8 数组+链表+红黑树,链表过长会严重影响HashMap的性能,红黑树搜索时间复杂度是O(logn),链表是O(n)。链表和红黑树的转换
- 当链表超过8且数据总量超过64才会转红黑树
- 将链表转换成红黑树前会判断,如果当前数组的长度小于64,会选择先进行数组扩容,而不是转换为红黑树,以减少搜索时间。
- 解决hash冲突
- 开放定址法(再散列法):以p为基础,再hash,以此类推,直到不冲突
- 再哈希法:提供多个hash函数,直到不冲突
- 链地址法:HashMap采用的方法。哈希值相同的元素构成一个单链表
- 建立公共溢出区:将哈希表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放到溢出区
- 加载因子
- Node[] table初始化长度为16,负载因子默认0.75,threshold是Hashmap所能容纳键值对的最大值,threshold=length*Load factor。在数组定义好长度之后,负载因子越大,所能容纳的键值对个数越多。
- 0.75是对空间和时间效率的一个平衡选择,一般不要修改,除非在时间和空间比较特殊的情况下
- 如果内存空间很多而又对时间效率要求很高,可以降低负载因子Load factor的值
- 如果内存空间紧张而对时间效率要求不高,可以增加负载因子loadFactory的值,这个值可以大于1
- key的存储索引怎么计算的
- 根据key的值计算出hashcode的值
- 根据hashcode计算出hash的值
- hash&(length-1)计算得到存储位置
- put流程
- 根据key计算出hash值,找到该元素再数组中存储的下标
- 如果数组是空的,调用resize进行初始化
- 如果没有哈希冲突直接放在对应的数组下标里
- 如果冲突,且key已经存在,覆盖掉value
- 如果冲突,发现该节点是红黑树,就将这个节点挂在树上
- 如果冲突后是链表,判断该链表是否大于8
- 如果大于8并且数组容量小于64,就扩容。
- 如果节点大于8并且数组容量大于64,结构转为红黑树,
- 否则,链表插入键值对,若key存在,就覆盖掉value
- 扩容
- 容量超过负载因子所定义的容量之后,就会扩容。将HashMap的大小扩大为原来数组的两倍,并将原来的对象放到新的数组中。
- 1.8两处优化
- resize之后,元素的位置在原来的位置或者原来位置+oldCap。如果bit是0,索引没变,如果是1则为原索引+oldcap
- 1.7中rehash的时候,旧链表迁移新链表的时候,如果在新表的数组索引位置相同,则链表元素会倒置(头插法),1.8不会倒置,使用尾插法。
- hashMap的key:一般用Integer,String这种不可变类当key,String最常用
- 因为字符串是不可变的,所以创建的时候hashcode就被缓存了,不需要重新计算
- 获取对象的时候要用到equals和hashcode,键对象正确的重写这两个方法是非常重要的。
- 为什么是线程不安全的
- 多线程下扩容死循环(1.7头插法导致的,1.8不会出现环形链表的问题)
- 多线程的put可能导致元素的丢失。如果计算出的索引位置相同,会造成前一个key被后一个key覆盖,从而导致元素丢失。
- put 和 get 并发时,可能导致get为null。线程1执行put,因为元素个数超出threshold导致rehash,线程2此时执行get,有可能导致这个问题。
7.ConcurrentHashMap
- 实现原理
- 1.7
- 由segment数组结构和HashEntry数组结构组成,把哈希桶切分成小数组,每个小数组有n个HashEntry组成。
- segment继承了ReentrantLock,所以segment是一种可重入锁,扮演锁的角色,HashEntry用于存储键值对数据
- 由segment数组结构和HashEntry数组结构组成,把哈希桶切分成小数组,每个小数组有n个HashEntry组成。
- 1.8
- 选择了与hashmap相同的数组+链表+红黑树结构。在锁的实现上,抛弃了原有的Segment分段锁,采用cas+synchronized实现更加低粒度的锁。将锁级别控制在了更细粒度的哈希桶元素级别,提高并发度
- 1.7
- put逻辑
- 1.7
- 尝试获取锁,获取失败,利用自旋获取锁,如果自旋重试次数超过64次,则改为阻塞获取锁
- 获取到锁后
- 将当前segment中的table通过key的hashcode定位到HashEntry
- 遍历该HashEntry,如果不为空则判断传入的key和当前遍历的key是否相等,相等则覆盖旧的value
- 不为空则需要新建一个HashEntry并加入到Segment中,同时会先判断是否需要扩容
- 释放segment的锁
- 1.8
- 根据key计算出hash的值
- 判断是否需要进行初始化
- 定位到Node,拿到首节点f,判断首节点f
- 如果为null,则通过cas的方式尝试添加
- 如果为f.hash=MOVED=-1,说明其他线程在扩容,参与一起扩容
- 如果都不满足,synchronized锁住f节点,判断是链表还是红黑树,遍历插入
- 当在链表长度达到8的时候数组扩容或者将链表转换为红黑树
- 1.7
- get方法不需要加锁
- Node的元素val和指针next是用volatile修饰的,在多线程环境下线程A修改节点的val或者新增节点的时候是对线程B可见的。
- 与volatile修饰的哈希桶没有关系:哈希桶主要是保证在数组扩容的时候保证可见性
- 不支持key或者value为null
- value不为null:无法判断是映射的value为null,还是没找到对应的key而为null。
- 并发度
- 1.7 默认16,可以在构造函数中设置,如果设置了并发度,ConcurrentHashMap会使用大于等于该值的最小的2的幂指数作为实际并发度,即如果设置的是17,则实际并发度为32
- 迭代器是强一致性还是弱一致性
- HashMap是强一致性,ConcurrentHashMap是弱一致性
- 迭代器创建后会按照哈希表结构遍历每个元素,在遍历过程中,内部元素可能发生变化,如果变化发生在已遍历过的部分,迭代器就不会反映出来,而如果变化发生在未遍历过的部分,迭代器会 发现并反映出来,即弱一致性。
8.Hashtable
- 使用Synchronized来实现线程安全,多线程访问的时候,只有一个线程能访问或操作对象。
9.多线程下安全的操作map还有其他方法么
- Collections.synchronizedMap:对方法进行加同步锁。如果传入的是HashMap对象,也是对HashMap做了一层包装,里面使用对象锁来保证多线程场景下线程安全,本质也是全表锁。
10.Collection框架中实现比较
- 内部比较器:实体类实现Comparable接口,并实现compareTo(T t)方法
- 外部比较器:实现Comparator接口的compare(T t1,T t2)
11.Iterator 和 ListIterator
- Iterator:遍历,可以遍历所有集合,eg:Map,List,Set,但只能再向前方向上遍历集合中的元素
- ListIterator:只能遍历List实现的对象,但可以向前和向后遍历集合中的元素
- 区别:
- 添加元素:Iterator无法向集合中添加元素,ListIterator可以向集合中添加元素
- 修改元素:Iterator无法修改元素,ListIterator可以使用set()修改集合中的元素
- 索引:Iterator无法获取集合中元素的索引,ListIterator可以获取结合中的索引
- 区别:
12.快速失败和安全失败
- 快速失败fail-fast
- 在用迭代器遍历一个集合对象时, 如果遍历过程中集合对象的内容进行了修改(增删改),则会抛出ConcurrentModificationException
- 原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个modCount变量,集合在被遍历期间如果内容发生变化,就会改变modCount的值,每当迭代器使用hashNext/next遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历,否则抛出异常,终止遍历。
- 注:这里异常的抛出条件是检测到modCount != expectedmodCount这个条件,如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出,因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug
- 场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改),比如hashmap,arrayList这些集合类
- 安全失败fail-safe
- 采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历
- 原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发ConcurrentModification Exception
- 缺点:基于拷贝内容的优点避免了ConcurrentModificationException,但同样滴,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的
- 场景:java.util.concurrent包下的容器都是安全失败的,可以在多线程下并发使用,并发修改,比如ConcurrentHashMap
相关文章:
java集合总结
1.常见集合 Collection List:有序可重复集合,可直接根据元素的索引来访问 Vector-StackArrayListLinkedList Queue:队列集合 Deque-LinkedList、ArrayDequePriorityQueue Set:无序不可重复集合,只能根据元素本身来访问…...

list交并补差集合
list交并补差集合 工具类依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version> </dependency><dependency><groupId>commons-collections&…...
【微信小程序】父组件修改子组件数据或调用子组件方法
一、使用场景 页面中用到了自定义组件形成父子组件关系,在父组件某个特定时期想要操作子组件中的数据或方法,比如离开页面的时候清空子组件的数据。 二、方法 父组件可以通过this.selectComponent方法获取子组件实例对象,这样就可以直接访…...
frp通过nginx映射multipart/x-mixed-replace; boundary=frame流媒体出外网访问
要通过Nginx访问multipart/x-mixed-replace流媒体协议,并通过FRP进行映射访问,你可以按照以下步骤进行操作: 配置Nginx以支持multipart/x-mixed-replace流媒体协议。你需要编辑Nginx的配置文件(通常是nginx.conf)&…...

Kubernetes概述
Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署(一)主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署(二)ETCD集群部署 Kubernetes高可用集群二进制部署(三)部署…...

Jmeter教程
目录 安装与配置 一:下载jdk——配置jdk环境变量 二:下载JMeter——配置环境变量 安装与配置 一:下载jdk——配置jdk环境变量 1.新建环境变量变量名:JAVA_HOME变量值:(即JDK的安装路径) 2.编辑Path%J…...
用Rust实现23种设计模式之建造者模式
当使用 Rust 实现建造者模式时,我们可以通过结构体和方法链来实现。建造者模式是一种创建型设计模式,它允许你按照特定的顺序构建复杂对象,同时使你能够灵活地构建不同的变体。下面是一个使用 Rust 实现建造者模式的示例, 在示例中…...

聚观早报 | 腾讯字节等企业驰援防汛救灾;新能源车7月销量单出炉
【聚观365】8月4日消息 腾讯字节等企业驰援防汛救灾新能源车7月销量成绩单出炉Model Y等车型低温续航衰减严重华为Mate60系列猜想图曝光支付宝做短视频引来羊毛党 腾讯字节等企业驰援防汛救灾 近日,京津冀地区遭遇极端降雨天气,引发洪涝和地质灾害&…...

Crack:CAD Exchanger SDK 3.20 Web Toolkit 应用
在CAD Exchanger SDK 版本 3.20.0中,我们在 Web Toolkit 中包含了绘图、BIM 和 MCAD 查看器的示例,以展示如何使用每个工具可视化数据。这些查看器具有显示不同类型数据的特定功能,允许用户根据自己的需求单独使用它们。我们将继续增强每个查…...
改造 ChatGPT-Next-Web 项目重新生成 Docker 镜像
改造 ChatGPT-Next-Web 项目重新生成 Docker 镜像 0.背景1. 修改代码2. 生成 Docker 镜像3. 上传 Docker 镜像4. 运行 Docker 镜像 0.背景 需要通过 ChatGPT-Next-Web 使用自己搭建的 OpenAI API 兼容的服务器,需要对 ChatGPT-Next-Web 项目的少量代码进行改造。 …...
git修改commit日志
由于公司对版本提交日志进行检查,如果不符合要求,则push失败。 以下是修改commit日志的方法: 1.进入到提交代码文件所在目录,即git所在目录下 cd app-repository 2.git log git log commit bf29e3e5e799d364fe2975677baf18c9…...

Qt之qml和widget混合编程调用
首先是创建一个widget项目 然后需要添加qml和quick的插件使用 QT quickwidgets qml 接着要在界面上创建一个quickwidget和按钮 创建一个c对象类 QObjectQml #ifndef QOBJECTQML_H #define QOBJECTQML_H#include <QObject> #include <QDebug> class QObjectQml …...
深度学习torch基础知识
torch. detach()拼接函数torch.stack()torch.nn.DataParallel()np.clip()torch.linspace()PyTorch中tensor.repeat()pytorch索引查找 index_select detach() detach是截断反向传播的梯度流 将某个node变成不需要梯度的Varibale。因此当反向传播经过这个node时,梯度…...

【JAVA】正则表达式是啥?
个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 文章目录 前言正则表达式正则表达式语法正则表达式的特点捕获组实例 前言 如果我们想要判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”),…...

网络安全之原型链污染
目录: 目录: 一、概念 二、举例 三、 实操了解 总结 四、抛出原题,历年原题复现 第一题: 五、分析与原理 第二题: 八、分析与原理 九、具体操作,payload与结果 结果: 一、概念 Java…...

【腾讯云Cloud Studio实战训练营】使用Cloud Studio迅捷开发一个3D家具个性化定制应用
目录 前言: 一、腾讯云 Cloud Studio介绍: 1、接近本地 IDE 的开发体验 2、多环境可选,或连接到云主机 3、随时分享预览效果 4、兼容 VSCode 插件 5、 AI代码助手 二、腾讯云Cloud Studio项目实践(3D家具个性化定制应用&…...

【计算机网络】第四章 网络层(一)
文章目录 第四章 网络层4.1 网络层概述4.2 网络层提供的两种服务4.2.1 小结 第四章 网络层 网络层是计算机网络体系结构中的一个关键层,位于传输层上方、数据链路层下方。它负责将传输层提供的数据分割成适当大小的数据包,并在不同网络之间进行路由选择和…...
Elasticsearch删除文档
根据id删除 例如删除id为110的文档 DELETE /ffbf/_doc/110返回信息 {"_index" : "ffbf","_type" : "_doc","_id" : "110","_version"...

MySQL数据库如何实现AX规范
本文我们来讨论 MySQL 的 XA 规范有哪些应用相关的内容。 MySQL 为我们提供了分布式事务解决方案,在前面的内容中 聊一聊分布式事务的解决方案 提到过 binlog 的同步,其实是 MySQL XA 规范的一个应用,那么 XA 规范是如何定义的,具…...

mac安装nvm
如果安装过node,须得卸载 sudo npm uninstall npm -gsudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.*sudo rm -rf /usr/local/include/node /Users/$USER/.npmsudo rm /usr/local/bin/nodesudo rm /usr/local/share/m…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...